shithub: freetype+ttf2subf

Download patch

ref: 328abf30946ad7c113db8e6bda4fdb4003ae6dda
parent: 87c0d30fc5fe512c8971510622091dd2c7a83031
author: Werner Lemberg <[email protected]>
date: Wed Dec 24 08:37:58 EST 2003

* src/cff/cffgload.c (cff_lookup_glyph_by_stdcharcode): Handle
CID-keyed fonts.

Remove MS-DOS line endings.

Minor formatting issues.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,40 +1,16 @@
-2003-12-23  David Turner  <[email protected]>
+2003-12-23  Werner Lemberg  <[email protected]>
 
-        * include/freetype/fttypes.h
-        src/autofit/afangles.c
-        src/autofit/aflatin.c
-        src/autohint/ahglyph.c
-        src/autohint/ahhint.c
-        src/base/ftcalc.c
-        src/base/ftgloadr.c
-        src/base/ftglyph.c
-        src/base/ftobjs.c
-        src/base/ftsynth.c
-        src/base/fttrigon.c
-        src/cff/cffgload.c
-        src/cid/cidgload.c
-        src/cid/cidload.c
-        src/pfr/pfrgload.c
-        src/pfr/pfrload.c
-        src/pfr/pfrsbit.c
-        src/psaux/psobjs.c
-        src/pshinter/pshalgo.c
-        src/pshinter/pshglob.c
-        src/pshinter/pshrec.c
-        src/raster/ftrend1.c
-        src/sfnt/ttcmap0.c
-        src/smooth/ftsmooth.c
-        src/truetype/ttdriver.c
-        src/truetype/ttgload.c
-        src/truetype/ttinterp.c
-        src/truetype/ttobjs.c
-        src/type1/t1gload.c
-        src/winfonts/winfnt.c:
+	* src/cff/cffgload.c (cff_lookup_glyph_by_stdcharcode): Handle
+	CID-keyed fonts.
 
-          use of the FT_PAD_XXX and FT_PIX_XXX macros to avoid compiler
-          warnings with very pedantic compilers. Hints:  (x) & -64 will
-          warn if (x) is not signed.. use (x) & ~63 instead !
+2003-12-23  David Turner  <[email protected]>
 
+	* include/freetype/internal/ftobjs.h (FT_PAD_FLOOR, FT_PAD_ROUND,
+	FT_PAD_CEIL, FT_PIX_FLOOR, FT_PIX_ROUND, FT_CEIL): New macros.  They
+	are used to avoid compiler warnings with very pedantic compilers. 
+	Note that `(x) & -64' causes a warning if (x) is not signed.  Use
+	`(x) & ~63' instead!
+	Updated all related code.
 
 2003-12-22  Werner Lemberg  <[email protected]>
 
--- a/include/freetype/cache/ftccache.h
+++ b/include/freetype/cache/ftccache.h
@@ -1,251 +1,251 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftccache.h                                                             */
-/*                                                                         */
-/*    FreeType internal cache interface (specification).                   */
-/*                                                                         */
-/*  Copyright 2000-2001, 2002 by                                           */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-#ifndef __FTCCACHE_H__
-#define __FTCCACHE_H__
-
-
-#include FT_CACHE_INTERNAL_MRU_H
-
-FT_BEGIN_HEADER
-
-  /* handle to cache object */
-  typedef struct FTC_CacheRec_*  FTC_Cache;
-
-  /* handle to cache class */
-  typedef const struct FTC_CacheClassRec_*  FTC_CacheClass;
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                   CACHE NODE DEFINITIONS                      *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Each cache controls one or more cache nodes.  Each node is part of    */
-  /* the global_lru list of the manager.  Its `data' field however is used */
-  /* as a reference count for now.                                         */
-  /*                                                                       */
-  /* A node can be anything, depending on the type of information held by  */
-  /* the cache.  It can be an individual glyph image, a set of bitmaps     */
-  /* glyphs for a given size, some metrics, etc.                           */
-  /*                                                                       */
-  /*************************************************************************/
-
-  /* structure size should be 20 bytes on 32-bits machines */
-  typedef struct  FTC_NodeRec_
-  {
-    FTC_MruNodeRec  mru;          /* circular mru list pointer           */
-    FTC_Node        link;         /* used for hashing                    */
-    FT_UInt32       hash;         /* used for hashing too                */
-    FT_UShort       cache_index;  /* index of cache the node belongs to  */
-    FT_Short        ref_count;    /* reference count for this node       */
-
-  } FTC_NodeRec;
-
-
-#define FTC_NODE( x )    ( (FTC_Node)(x) )
-#define FTC_NODE_P( x )  ( (FTC_Node*)(x) )
-
-#define FTC_NODE__NEXT(x)  FTC_NODE( (x)->mru.next )
-#define FTC_NODE__PREV(x)  FTC_NODE( (x)->mru.prev )
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* These functions are exported so that they can be called from          */
-  /* user-provided cache classes; otherwise, they are really part of the   */
-  /* cache sub-system internals.                                           */
-  /*                                                                       */
-
-  /* reserved for manager's use */
-  FT_EXPORT( void )
-  ftc_node_destroy( FTC_Node     node,
-                    FTC_Manager  manager );
-
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                       CACHE DEFINITIONS                       *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  /* initialize a new cache node */
-  typedef FT_Error    (*FTC_Node_NewFunc)( FTC_Node    *pnode,
-                                           FT_Pointer   query,
-                                           FTC_Cache    cache );
-
-  typedef FT_ULong    (*FTC_Node_WeightFunc)( FTC_Node   node,
-                                              FTC_Cache  cache );
-
-  /* compare a node to a given key pair */
-  typedef FT_Bool     (*FTC_Node_CompareFunc)( FTC_Node    node,
-                                               FT_Pointer  key,
-                                               FTC_Cache   cache );
-
-
-  typedef void        (*FTC_Node_FreeFunc)( FTC_Node   node,
-                                            FTC_Cache  cache );
-
-  typedef FT_Error    (*FTC_Cache_InitFunc)( FTC_Cache   cache );
-
-  typedef void        (*FTC_Cache_DoneFunc)( FTC_Cache   cache );
-
-
-  typedef struct FTC_CacheClassRec_
-  {
-    FTC_Node_NewFunc        node_new;
-    FTC_Node_WeightFunc     node_weight;
-    FTC_Node_CompareFunc    node_compare;
-    FTC_Node_CompareFunc    node_remove_faceid;
-    FTC_Node_FreeFunc       node_free;
-
-    FT_UInt                 cache_size;
-    FTC_Cache_InitFunc      cache_init;
-    FTC_Cache_DoneFunc      cache_done;
-
-  } FTC_CacheClassRec;
-
-  /* each cache really implements a dynamic hash table to manage its nodes */
-  typedef struct  FTC_CacheRec_
-  {
-    FT_UFast             p;
-    FT_UFast             mask;
-    FT_Long              slack;
-    FTC_Node*            buckets;
-
-    FTC_CacheClassRec    clazz;      /* local copy, for speed */
-
-    FTC_Manager          manager;
-    FT_Memory            memory;
-    FT_UInt              index;  /* in manager's table         */
-
-    FTC_CacheClass       org_class;  /* original class pointer */
-
-  } FTC_CacheRec;
-
-
-#define FTC_CACHE( x )    ( (FTC_Cache)(x) )
-#define FTC_CACHE_P( x )  ( (FTC_Cache*)(x) )
-
-
- /* default cache initialize */
-  FT_EXPORT( FT_Error )
-  FTC_Cache_Init( FTC_Cache       cache );
-
- /* default cache finalizer */
-  FT_EXPORT( void )
-  FTC_Cache_Done( FTC_Cache  cache );
-
- /* call this function to lookup the cache. if no corresponding
-  * node is found, a new one is automatically created. This function
-  * is capable of flushing the cache adequately to make room for the
-  * new cache object.
-  */
-  FT_EXPORT( FT_Error )
-  FTC_Cache_Lookup( FTC_Cache   cache,
-                    FT_UInt32   hash,
-                    FT_Pointer  query,
-                    FTC_Node   *anode );
-
-  FT_EXPORT( FT_Error )
-  FTC_Cache_NewNode( FTC_Cache   cache,
-                     FT_UInt32   hash,
-                     FT_Pointer  query,
-                     FTC_Node   *anode );
-
- /* remove all nodes that relate to a given face_id. This is useful
-  * when un-installing fonts. Note that if a cache node relates to
-  * the face_id, but is locked (i.e. has 'ref_count > 0'), the node
-  * will _not_ be destroyed, but its internal face_id reference will
-  * be modified.
-  *
-  * the end result will be that the node will never come back
-  * in further lookup requests, and will be flushed on demand from
-  * the cache normally when its reference count reaches 0
-  */
-  FT_EXPORT( void )
-  FTC_Cache_RemoveFaceID( FTC_Cache    cache,
-                          FTC_FaceID   face_id );
-
-
-
-#define  FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error )  \
-  FT_BEGIN_STMNT                                                           \
-    FTC_Node  *_bucket, *_pnode, _node;                                    \
-    FTC_Cache  _cache = FTC_CACHE(cache);                                  \
-    FT_UInt32  _hash  = (FT_UInt32)(hash);                                 \
-    FTC_Node_CompareFunc  _nodcomp = (FTC_Node_CompareFunc)(nodecmp);      \
-    FT_UInt    _idx;                                                       \
-                                                                           \
-    error = 0;                                                             \
-    _idx  = _hash & _cache->mask;                                          \
-    if ( _idx < _cache->p )                                                \
-      _idx = _hash & (_cache->mask*2 + 1);                                 \
-                                                                           \
-    _bucket = _pnode = _cache->buckets + _idx;                             \
-    for (;;)                                                               \
-    {                                                                      \
-      _node = *_pnode;                                                     \
-      if ( _node == NULL )                                                 \
-        goto _NewNode;                                                      \
-                                                                           \
-      if ( _node->hash == _hash && _nodcomp( _node, query, _cache ) )      \
-        break;                                                             \
-                                                                           \
-      _pnode = &_node->link;                                               \
-    }                                                                      \
-                                                                           \
-    if ( _node != *_bucket )                                               \
-    {                                                                      \
-      *_pnode     = _node->link;                                           \
-      _node->link = *_bucket;                                              \
-      *_bucket    = _node;                                                 \
-    }                                                                      \
-                                                                           \
-    {                                                                      \
-      FTC_Manager  _manager = _cache->manager;                             \
-                                                                           \
-      if ( _node != _manager->nodes_list )                                 \
-        FTC_MruNode_Up( (FTC_MruNode*)&_manager->nodes_list,               \
-                        (FTC_MruNode)_node );                              \
-    }                                                                      \
-    goto _Ok;                                                              \
-                                                                           \
-  _NewNode:                                                                \
-    error = FTC_Cache_NewNode( _cache, _hash, query, &_node );             \
-                                                                           \
-  _Ok:                                                                     \
-    *(FTC_Node*)&(node) = _node;                                           \
-  FT_END_STMNT
-
-
- /* */
-
-FT_END_HEADER
-
-
-#endif /* __FTCCACHE_H__ */
-
-
-/* END */
+/***************************************************************************/
+/*                                                                         */
+/*  ftccache.h                                                             */
+/*                                                                         */
+/*    FreeType internal cache interface (specification).                   */
+/*                                                                         */
+/*  Copyright 2000-2001, 2002 by                                           */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef __FTCCACHE_H__
+#define __FTCCACHE_H__
+
+
+#include FT_CACHE_INTERNAL_MRU_H
+
+FT_BEGIN_HEADER
+
+  /* handle to cache object */
+  typedef struct FTC_CacheRec_*  FTC_Cache;
+
+  /* handle to cache class */
+  typedef const struct FTC_CacheClassRec_*  FTC_CacheClass;
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                   CACHE NODE DEFINITIONS                      *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Each cache controls one or more cache nodes.  Each node is part of    */
+  /* the global_lru list of the manager.  Its `data' field however is used */
+  /* as a reference count for now.                                         */
+  /*                                                                       */
+  /* A node can be anything, depending on the type of information held by  */
+  /* the cache.  It can be an individual glyph image, a set of bitmaps     */
+  /* glyphs for a given size, some metrics, etc.                           */
+  /*                                                                       */
+  /*************************************************************************/
+
+  /* structure size should be 20 bytes on 32-bits machines */
+  typedef struct  FTC_NodeRec_
+  {
+    FTC_MruNodeRec  mru;          /* circular mru list pointer           */
+    FTC_Node        link;         /* used for hashing                    */
+    FT_UInt32       hash;         /* used for hashing too                */
+    FT_UShort       cache_index;  /* index of cache the node belongs to  */
+    FT_Short        ref_count;    /* reference count for this node       */
+
+  } FTC_NodeRec;
+
+
+#define FTC_NODE( x )    ( (FTC_Node)(x) )
+#define FTC_NODE_P( x )  ( (FTC_Node*)(x) )
+
+#define FTC_NODE__NEXT(x)  FTC_NODE( (x)->mru.next )
+#define FTC_NODE__PREV(x)  FTC_NODE( (x)->mru.prev )
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* These functions are exported so that they can be called from          */
+  /* user-provided cache classes; otherwise, they are really part of the   */
+  /* cache sub-system internals.                                           */
+  /*                                                                       */
+
+  /* reserved for manager's use */
+  FT_EXPORT( void )
+  ftc_node_destroy( FTC_Node     node,
+                    FTC_Manager  manager );
+
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                       CACHE DEFINITIONS                       *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /* initialize a new cache node */
+  typedef FT_Error    (*FTC_Node_NewFunc)( FTC_Node    *pnode,
+                                           FT_Pointer   query,
+                                           FTC_Cache    cache );
+
+  typedef FT_ULong    (*FTC_Node_WeightFunc)( FTC_Node   node,
+                                              FTC_Cache  cache );
+
+  /* compare a node to a given key pair */
+  typedef FT_Bool     (*FTC_Node_CompareFunc)( FTC_Node    node,
+                                               FT_Pointer  key,
+                                               FTC_Cache   cache );
+
+
+  typedef void        (*FTC_Node_FreeFunc)( FTC_Node   node,
+                                            FTC_Cache  cache );
+
+  typedef FT_Error    (*FTC_Cache_InitFunc)( FTC_Cache   cache );
+
+  typedef void        (*FTC_Cache_DoneFunc)( FTC_Cache   cache );
+
+
+  typedef struct FTC_CacheClassRec_
+  {
+    FTC_Node_NewFunc        node_new;
+    FTC_Node_WeightFunc     node_weight;
+    FTC_Node_CompareFunc    node_compare;
+    FTC_Node_CompareFunc    node_remove_faceid;
+    FTC_Node_FreeFunc       node_free;
+
+    FT_UInt                 cache_size;
+    FTC_Cache_InitFunc      cache_init;
+    FTC_Cache_DoneFunc      cache_done;
+
+  } FTC_CacheClassRec;
+
+  /* each cache really implements a dynamic hash table to manage its nodes */
+  typedef struct  FTC_CacheRec_
+  {
+    FT_UFast             p;
+    FT_UFast             mask;
+    FT_Long              slack;
+    FTC_Node*            buckets;
+
+    FTC_CacheClassRec    clazz;      /* local copy, for speed */
+
+    FTC_Manager          manager;
+    FT_Memory            memory;
+    FT_UInt              index;  /* in manager's table         */
+
+    FTC_CacheClass       org_class;  /* original class pointer */
+
+  } FTC_CacheRec;
+
+
+#define FTC_CACHE( x )    ( (FTC_Cache)(x) )
+#define FTC_CACHE_P( x )  ( (FTC_Cache*)(x) )
+
+
+ /* default cache initialize */
+  FT_EXPORT( FT_Error )
+  FTC_Cache_Init( FTC_Cache       cache );
+
+ /* default cache finalizer */
+  FT_EXPORT( void )
+  FTC_Cache_Done( FTC_Cache  cache );
+
+ /* call this function to lookup the cache. if no corresponding
+  * node is found, a new one is automatically created. This function
+  * is capable of flushing the cache adequately to make room for the
+  * new cache object.
+  */
+  FT_EXPORT( FT_Error )
+  FTC_Cache_Lookup( FTC_Cache   cache,
+                    FT_UInt32   hash,
+                    FT_Pointer  query,
+                    FTC_Node   *anode );
+
+  FT_EXPORT( FT_Error )
+  FTC_Cache_NewNode( FTC_Cache   cache,
+                     FT_UInt32   hash,
+                     FT_Pointer  query,
+                     FTC_Node   *anode );
+
+ /* remove all nodes that relate to a given face_id. This is useful
+  * when un-installing fonts. Note that if a cache node relates to
+  * the face_id, but is locked (i.e. has 'ref_count > 0'), the node
+  * will _not_ be destroyed, but its internal face_id reference will
+  * be modified.
+  *
+  * the end result will be that the node will never come back
+  * in further lookup requests, and will be flushed on demand from
+  * the cache normally when its reference count reaches 0
+  */
+  FT_EXPORT( void )
+  FTC_Cache_RemoveFaceID( FTC_Cache    cache,
+                          FTC_FaceID   face_id );
+
+
+
+#define  FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error )  \
+  FT_BEGIN_STMNT                                                           \
+    FTC_Node  *_bucket, *_pnode, _node;                                    \
+    FTC_Cache  _cache = FTC_CACHE(cache);                                  \
+    FT_UInt32  _hash  = (FT_UInt32)(hash);                                 \
+    FTC_Node_CompareFunc  _nodcomp = (FTC_Node_CompareFunc)(nodecmp);      \
+    FT_UInt    _idx;                                                       \
+                                                                           \
+    error = 0;                                                             \
+    _idx  = _hash & _cache->mask;                                          \
+    if ( _idx < _cache->p )                                                \
+      _idx = _hash & (_cache->mask*2 + 1);                                 \
+                                                                           \
+    _bucket = _pnode = _cache->buckets + _idx;                             \
+    for (;;)                                                               \
+    {                                                                      \
+      _node = *_pnode;                                                     \
+      if ( _node == NULL )                                                 \
+        goto _NewNode;                                                      \
+                                                                           \
+      if ( _node->hash == _hash && _nodcomp( _node, query, _cache ) )      \
+        break;                                                             \
+                                                                           \
+      _pnode = &_node->link;                                               \
+    }                                                                      \
+                                                                           \
+    if ( _node != *_bucket )                                               \
+    {                                                                      \
+      *_pnode     = _node->link;                                           \
+      _node->link = *_bucket;                                              \
+      *_bucket    = _node;                                                 \
+    }                                                                      \
+                                                                           \
+    {                                                                      \
+      FTC_Manager  _manager = _cache->manager;                             \
+                                                                           \
+      if ( _node != _manager->nodes_list )                                 \
+        FTC_MruNode_Up( (FTC_MruNode*)&_manager->nodes_list,               \
+                        (FTC_MruNode)_node );                              \
+    }                                                                      \
+    goto _Ok;                                                              \
+                                                                           \
+  _NewNode:                                                                \
+    error = FTC_Cache_NewNode( _cache, _hash, query, &_node );             \
+                                                                           \
+  _Ok:                                                                     \
+    *(FTC_Node*)&(node) = _node;                                           \
+  FT_END_STMNT
+
+
+ /* */
+
+FT_END_HEADER
+
+
+#endif /* __FTCCACHE_H__ */
+
+
+/* END */
--- a/include/freetype/cache/ftcglyph.h
+++ b/include/freetype/cache/ftcglyph.h
@@ -1,295 +1,295 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftcglyph.h                                                             */
-/*                                                                         */
-/*    FreeType abstract glyph cache (specification).                       */
-/*                                                                         */
-/*  Copyright 2000-2001, 2003 by                                           */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-  /*
-   *
-   *  FTC_GCache is an _abstract_ cache object optimized to store glyph
-   *  data. It works as follows:
-   *
-   *   - it manages FTC_GNode objects. Each one of them can hold one or more
-   *     glyph "items". Item types are not specified in the FTC_GCache but in
-   *     classes that extend it
-   *
-   *   - glyph attributes, like face_id, character size, render mode, etc..
-   *     can be grouped in abstract "glyph families". This avoids storing
-   *     the attributes within the FTC_GCache, since it is likely that many
-   *     FTC_GNodes will belong to the same family in typical uses
-   *
-   *   - each FTC_GNode is thus a FTC_Node with two additionnal fields:
-   *
-   *       * gindex :: a glyph index, or the first index in a glyph range
-   *       * family :: a pointer to a glyph "family"
-   *
-   *   - Family types are not fully specific in the FTC_Family type, but
-   *     by classes that extend it.
-   *
-   *  Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache. They
-   *  share an FTC_Family sub-class called FTC_BasicFamily which is used to
-   *  store the following data:  face_id, pixel/point sizes, load flags.
-   *  for more details, see the file "src/cache/ftcbasic.c"
-   *
-   *  Client applications can extend FTC_GNode with their own FTC_GNode
-   *  and FTC_Family sub-classes to implement more complex caches (e.g.
-   *  handling automatic synthetis, like obliquing & emboldening, colored
-   *  glyphs, etc...)
-   *
-   *  See also the FTC_ICache & FTC_SCache classes in "ftcimage.h" and
-   *  "ftcsbits.h", which both extend FTC_GCache with additionnal
-   *  optimizations.
-   *
-   *
-   *  a typical FTC_GCache implementation must provide at least the following:
-   *
-   *  - FTC_GNode sub-class, e.g. MyNode, with relevant methods, i.e:
-   *        my_node_new            ( must call FTC_GNode_Init )
-   *        my_node_free           ( must call FTC_GNode_Done )
-   *        my_node_compare        ( must call FTC_GNode_Compare )
-   *        my_node_remove_faceid  ( must call ftc_gnode_unselect in case
-   *                                 of match )
-   *
-   *
-   *  - FTC_Family sub-class, e.g. MyFamily, with relevant methods, e.g.:
-   *        my_family_compare
-   *        my_family_init
-   *        my_family_reset (optional)
-   *        my_family_done
-   *
-   *  - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query
-   *    data.
-   *
-   *  - provide constant structures for a FTC_GNodeClass
-   *
-   *  - MyCacheNew() can be implemented easily as a call to the convenience
-   *    function FTC_GCache_New
-   *
-   *  - implement MyCacheLookup with a call to FTC_GCache_Lookup. This
-   *    function will automatically:
-   *
-   *      - search for the corresponding family in the cache, or create
-   *        a new one if necessary. put it in FTC_GQUERY(myquery).family
-   *
-   *      - call FTC_Cache_Lookup
-   *
-   *    if it returns NULL, you should create a new node, then call
-   *    ftc_cache_add as usual.
-   */
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Important: The functions defined in this file are only used to        */
-  /*            implement an abstract glyph cache class.  You need to      */
-  /*            provide additional logic to implement a complete cache.    */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*********                                                       *********/
-  /*********             WARNING, THIS IS BETA CODE.               *********/
-  /*********                                                       *********/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-#ifndef __FTCGLYPH_H__
-#define __FTCGLYPH_H__
-
-
-#include <ft2build.h>
-#include FT_CACHE_INTERNAL_MANAGER_H
-
-
-FT_BEGIN_HEADER
-
-
- /*
-  *  we can group glyph in "families". Each family correspond to a
-  *  given face id, character size, transform, etc...
-  *
-  *  families are implemented as MRU list nodes. They are reference-counted
-  */
-
-  typedef struct  FTC_FamilyRec_
-  {
-    FTC_MruNodeRec    mrunode;
-    FT_UInt           num_nodes;   /* current number of nodes in this family */
-    FTC_Cache         cache;
-    FTC_MruListClass  clazz;
-
-  } FTC_FamilyRec, *FTC_Family;
-
-#define  FTC_FAMILY(x)    ( (FTC_Family)(x) )
-#define  FTC_FAMILY_P(x)  ( (FTC_Family*)(x) )
-
-
-  typedef struct  FTC_GNodeRec_
-  {
-    FTC_NodeRec      node;
-    FTC_Family       family;
-    FT_UInt          gindex;
-
-  } FTC_GNodeRec, *FTC_GNode;
-
-#define FTC_GNODE( x )    ( (FTC_GNode)(x) )
-#define FTC_GNODE_P( x )  ( (FTC_GNode*)(x) )
-
-
-  typedef struct  FTC_GQueryRec_
-  {
-    FT_UInt      gindex;
-    FTC_Family   family;
-
-  } FTC_GQueryRec, *FTC_GQuery;
-
-#define FTC_GQUERY( x )  ( (FTC_GQuery)(x) )
-
-
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* These functions are exported so that they can be called from          */
-  /* user-provided cache classes; otherwise, they are really part of the   */
-  /* cache sub-system internals.                                           */
-  /*                                                                       */
-
-  /* must be called by derived FTC_Node_InitFunc routines */
-  FT_EXPORT( void )
-  FTC_GNode_Init( FTC_GNode    node,
-                  FT_UInt      gindex,  /* glyph index for node */
-                  FTC_Family   family );
-
-  /* returns TRUE iff the query's glyph index correspond to the node;  */
-  /* this assumes that the "family" and "hash" fields of the query are */
-  /* already correctly set                                             */
-  FT_EXPORT( FT_Bool )
-  FTC_GNode_Compare( FTC_GNode   gnode,
-                     FTC_GQuery  gquery );
-
- /* call this function to clear a node's family. this is necessary
-  * to implement the "node_remove_faceid" cache method correctly
-  */
-  FT_EXPORT( void )
-  FTC_GNode_UnselectFamily( FTC_GNode   gnode,
-                            FTC_Cache   cache );
-
-  /* must be called by derived FTC_Node_DoneFunc routines */
-  FT_EXPORT( void )
-  FTC_GNode_Done( FTC_GNode  node,
-                  FTC_Cache      cache );
-
-
-  FT_EXPORT( void )
-  FTC_Family_Init( FTC_Family  family,
-                   FTC_Cache   cache );
-
-  typedef struct FTC_GCacheRec_
-  {
-    FTC_CacheRec       cache;
-    FTC_MruListRec     families;
-
-  } FTC_GCacheRec, *FTC_GCache;
-
-
-#define FTC_GCACHE(x)  ((FTC_GCache)(x))
-
-
- /* can be used as @FTC_Cache_InitFunc */
-  FT_EXPORT( FT_Error )
-  FTC_GCache_Init( FTC_GCache     cache );
-
-
- /* can be used as @FTC_Cache_DoneFunc */
-  FT_EXPORT( void )
-  FTC_GCache_Done( FTC_GCache  cache );
-
-
- /* the glyph cache class adds fields for the family implementation */
-  typedef struct FTC_GCacheClassRec_
-  {
-    FTC_CacheClassRec  clazz;
-    FTC_MruListClass   family_class;
-
-  } FTC_GCacheClassRec;
-
-  typedef const FTC_GCacheClassRec*   FTC_GCacheClass;
-
-#define  FTC_GCACHE_CLASS(x)  ((FTC_GCacheClass)(x))
-
-#define  FTC_CACHE__GCACHE_CLASS(x)  FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class )
-#define  FTC_CACHE__FAMILY_CLASS(x)  ((FTC_MruListClass) FTC_CACHE__GCACHE_CLASS(x)->family_class)
-
-
- /* convenience function. use instead of FTC_Manager_Register_Cache */
-  FT_EXPORT( FT_Error )
-  FTC_GCache_New( FTC_Manager       manager,
-                  FTC_GCacheClass   clazz,
-                  FTC_GCache       *acache );
-
-  FT_EXPORT( FT_Error )
-  FTC_GCache_Lookup( FTC_GCache   cache,
-                     FT_UInt32    hash,
-                     FT_UInt      gindex,
-                     FTC_GQuery   query,
-                     FTC_Node    *anode );
-
-
-#define  FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, gindex, query, node, error )  \
-  FT_BEGIN_STMNT                                                                   \
-    FTC_GCache               _gcache   = FTC_GCACHE( cache );                      \
-    FTC_Family               _family;                                              \
-    FTC_GQuery               _gquery   = (FTC_GQuery)( query );                    \
-    FTC_MruNode_CompareFunc  _fcompare = (FTC_MruNode_CompareFunc)(famcmp);        \
-                                                                                   \
-    _gquery->gindex = (gindex);                                                    \
-                                                                                   \
-    FTC_MRULIST_LOOP( &_gcache->families, _family )                                \
-    {                                                                      \
-      if ( _fcompare( (FTC_MruNode)_family, _gquery ) )                    \
-      {                                                                    \
-        _gquery->family = _family;                                         \
-        goto _FamilyFound;                                                 \
-      }                                                                    \
-    }                                                                      \
-    FTC_MRULIST_LOOP_END();                                                \
-                                                                           \
-    error = FTC_MruList_New( &_gcache->families,                           \
-                             _gquery,                                      \
-                             (FTC_MruNode*)&_gquery->family );             \
-    if ( !error )                                                          \
-    {                                                                      \
-    _FamilyFound:                                                          \
-      FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error );    \
-    }                                                                      \
-  FT_END_STMNT
-  /* */
-
-FT_END_HEADER
-
-
-#endif /* __FTCGLYPH_H__ */
-
-
-/* END */
+/***************************************************************************/
+/*                                                                         */
+/*  ftcglyph.h                                                             */
+/*                                                                         */
+/*    FreeType abstract glyph cache (specification).                       */
+/*                                                                         */
+/*  Copyright 2000-2001, 2003 by                                           */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*
+   *
+   *  FTC_GCache is an _abstract_ cache object optimized to store glyph
+   *  data. It works as follows:
+   *
+   *   - it manages FTC_GNode objects. Each one of them can hold one or more
+   *     glyph "items". Item types are not specified in the FTC_GCache but in
+   *     classes that extend it
+   *
+   *   - glyph attributes, like face_id, character size, render mode, etc..
+   *     can be grouped in abstract "glyph families". This avoids storing
+   *     the attributes within the FTC_GCache, since it is likely that many
+   *     FTC_GNodes will belong to the same family in typical uses
+   *
+   *   - each FTC_GNode is thus a FTC_Node with two additionnal fields:
+   *
+   *       * gindex :: a glyph index, or the first index in a glyph range
+   *       * family :: a pointer to a glyph "family"
+   *
+   *   - Family types are not fully specific in the FTC_Family type, but
+   *     by classes that extend it.
+   *
+   *  Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache. They
+   *  share an FTC_Family sub-class called FTC_BasicFamily which is used to
+   *  store the following data:  face_id, pixel/point sizes, load flags.
+   *  for more details, see the file "src/cache/ftcbasic.c"
+   *
+   *  Client applications can extend FTC_GNode with their own FTC_GNode
+   *  and FTC_Family sub-classes to implement more complex caches (e.g.
+   *  handling automatic synthetis, like obliquing & emboldening, colored
+   *  glyphs, etc...)
+   *
+   *  See also the FTC_ICache & FTC_SCache classes in "ftcimage.h" and
+   *  "ftcsbits.h", which both extend FTC_GCache with additionnal
+   *  optimizations.
+   *
+   *
+   *  a typical FTC_GCache implementation must provide at least the following:
+   *
+   *  - FTC_GNode sub-class, e.g. MyNode, with relevant methods, i.e:
+   *        my_node_new            ( must call FTC_GNode_Init )
+   *        my_node_free           ( must call FTC_GNode_Done )
+   *        my_node_compare        ( must call FTC_GNode_Compare )
+   *        my_node_remove_faceid  ( must call ftc_gnode_unselect in case
+   *                                 of match )
+   *
+   *
+   *  - FTC_Family sub-class, e.g. MyFamily, with relevant methods, e.g.:
+   *        my_family_compare
+   *        my_family_init
+   *        my_family_reset (optional)
+   *        my_family_done
+   *
+   *  - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query
+   *    data.
+   *
+   *  - provide constant structures for a FTC_GNodeClass
+   *
+   *  - MyCacheNew() can be implemented easily as a call to the convenience
+   *    function FTC_GCache_New
+   *
+   *  - implement MyCacheLookup with a call to FTC_GCache_Lookup. This
+   *    function will automatically:
+   *
+   *      - search for the corresponding family in the cache, or create
+   *        a new one if necessary. put it in FTC_GQUERY(myquery).family
+   *
+   *      - call FTC_Cache_Lookup
+   *
+   *    if it returns NULL, you should create a new node, then call
+   *    ftc_cache_add as usual.
+   */
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Important: The functions defined in this file are only used to        */
+  /*            implement an abstract glyph cache class.  You need to      */
+  /*            provide additional logic to implement a complete cache.    */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*********                                                       *********/
+  /*********             WARNING, THIS IS BETA CODE.               *********/
+  /*********                                                       *********/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+#ifndef __FTCGLYPH_H__
+#define __FTCGLYPH_H__
+
+
+#include <ft2build.h>
+#include FT_CACHE_INTERNAL_MANAGER_H
+
+
+FT_BEGIN_HEADER
+
+
+ /*
+  *  we can group glyph in "families". Each family correspond to a
+  *  given face id, character size, transform, etc...
+  *
+  *  families are implemented as MRU list nodes. They are reference-counted
+  */
+
+  typedef struct  FTC_FamilyRec_
+  {
+    FTC_MruNodeRec    mrunode;
+    FT_UInt           num_nodes;   /* current number of nodes in this family */
+    FTC_Cache         cache;
+    FTC_MruListClass  clazz;
+
+  } FTC_FamilyRec, *FTC_Family;
+
+#define  FTC_FAMILY(x)    ( (FTC_Family)(x) )
+#define  FTC_FAMILY_P(x)  ( (FTC_Family*)(x) )
+
+
+  typedef struct  FTC_GNodeRec_
+  {
+    FTC_NodeRec      node;
+    FTC_Family       family;
+    FT_UInt          gindex;
+
+  } FTC_GNodeRec, *FTC_GNode;
+
+#define FTC_GNODE( x )    ( (FTC_GNode)(x) )
+#define FTC_GNODE_P( x )  ( (FTC_GNode*)(x) )
+
+
+  typedef struct  FTC_GQueryRec_
+  {
+    FT_UInt      gindex;
+    FTC_Family   family;
+
+  } FTC_GQueryRec, *FTC_GQuery;
+
+#define FTC_GQUERY( x )  ( (FTC_GQuery)(x) )
+
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* These functions are exported so that they can be called from          */
+  /* user-provided cache classes; otherwise, they are really part of the   */
+  /* cache sub-system internals.                                           */
+  /*                                                                       */
+
+  /* must be called by derived FTC_Node_InitFunc routines */
+  FT_EXPORT( void )
+  FTC_GNode_Init( FTC_GNode    node,
+                  FT_UInt      gindex,  /* glyph index for node */
+                  FTC_Family   family );
+
+  /* returns TRUE iff the query's glyph index correspond to the node;  */
+  /* this assumes that the "family" and "hash" fields of the query are */
+  /* already correctly set                                             */
+  FT_EXPORT( FT_Bool )
+  FTC_GNode_Compare( FTC_GNode   gnode,
+                     FTC_GQuery  gquery );
+
+ /* call this function to clear a node's family. this is necessary
+  * to implement the "node_remove_faceid" cache method correctly
+  */
+  FT_EXPORT( void )
+  FTC_GNode_UnselectFamily( FTC_GNode   gnode,
+                            FTC_Cache   cache );
+
+  /* must be called by derived FTC_Node_DoneFunc routines */
+  FT_EXPORT( void )
+  FTC_GNode_Done( FTC_GNode  node,
+                  FTC_Cache      cache );
+
+
+  FT_EXPORT( void )
+  FTC_Family_Init( FTC_Family  family,
+                   FTC_Cache   cache );
+
+  typedef struct FTC_GCacheRec_
+  {
+    FTC_CacheRec       cache;
+    FTC_MruListRec     families;
+
+  } FTC_GCacheRec, *FTC_GCache;
+
+
+#define FTC_GCACHE(x)  ((FTC_GCache)(x))
+
+
+ /* can be used as @FTC_Cache_InitFunc */
+  FT_EXPORT( FT_Error )
+  FTC_GCache_Init( FTC_GCache     cache );
+
+
+ /* can be used as @FTC_Cache_DoneFunc */
+  FT_EXPORT( void )
+  FTC_GCache_Done( FTC_GCache  cache );
+
+
+ /* the glyph cache class adds fields for the family implementation */
+  typedef struct FTC_GCacheClassRec_
+  {
+    FTC_CacheClassRec  clazz;
+    FTC_MruListClass   family_class;
+
+  } FTC_GCacheClassRec;
+
+  typedef const FTC_GCacheClassRec*   FTC_GCacheClass;
+
+#define  FTC_GCACHE_CLASS(x)  ((FTC_GCacheClass)(x))
+
+#define  FTC_CACHE__GCACHE_CLASS(x)  FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class )
+#define  FTC_CACHE__FAMILY_CLASS(x)  ((FTC_MruListClass) FTC_CACHE__GCACHE_CLASS(x)->family_class)
+
+
+ /* convenience function. use instead of FTC_Manager_Register_Cache */
+  FT_EXPORT( FT_Error )
+  FTC_GCache_New( FTC_Manager       manager,
+                  FTC_GCacheClass   clazz,
+                  FTC_GCache       *acache );
+
+  FT_EXPORT( FT_Error )
+  FTC_GCache_Lookup( FTC_GCache   cache,
+                     FT_UInt32    hash,
+                     FT_UInt      gindex,
+                     FTC_GQuery   query,
+                     FTC_Node    *anode );
+
+
+#define  FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, gindex, query, node, error )  \
+  FT_BEGIN_STMNT                                                                   \
+    FTC_GCache               _gcache   = FTC_GCACHE( cache );                      \
+    FTC_Family               _family;                                              \
+    FTC_GQuery               _gquery   = (FTC_GQuery)( query );                    \
+    FTC_MruNode_CompareFunc  _fcompare = (FTC_MruNode_CompareFunc)(famcmp);        \
+                                                                                   \
+    _gquery->gindex = (gindex);                                                    \
+                                                                                   \
+    FTC_MRULIST_LOOP( &_gcache->families, _family )                                \
+    {                                                                      \
+      if ( _fcompare( (FTC_MruNode)_family, _gquery ) )                    \
+      {                                                                    \
+        _gquery->family = _family;                                         \
+        goto _FamilyFound;                                                 \
+      }                                                                    \
+    }                                                                      \
+    FTC_MRULIST_LOOP_END();                                                \
+                                                                           \
+    error = FTC_MruList_New( &_gcache->families,                           \
+                             _gquery,                                      \
+                             (FTC_MruNode*)&_gquery->family );             \
+    if ( !error )                                                          \
+    {                                                                      \
+    _FamilyFound:                                                          \
+      FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error );    \
+    }                                                                      \
+  FT_END_STMNT
+  /* */
+
+FT_END_HEADER
+
+
+#endif /* __FTCGLYPH_H__ */
+
+
+/* END */
--- a/include/freetype/cache/ftcmru.h
+++ b/include/freetype/cache/ftcmru.h
@@ -1,227 +1,227 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftcmru.h                                                               */
-/*                                                                         */
-/*    Simple MRU list-cache (specification).                               */
-/*                                                                         */
-/*  Copyright 2000-2001, 2003 by                                           */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* An MRU is a list that cannot hold more than a certain number of       */
-  /* elements (`max_elements').  All elements in the list are sorted in    */
-  /* least-recently-used order, i.e., the `oldest' element is at the tail  */
-  /* of the list.                                                          */
-  /*                                                                       */
-  /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'),   */
-  /* the list is searched for an element with the corresponding key.  If   */
-  /* it is found, the element is moved to the head of the list and is      */
-  /* returned.                                                             */
-  /*                                                                       */
-  /* If no corresponding element is found, the lookup routine will try to  */
-  /* obtain a new element with the relevant key.  If the list is already   */
-  /* full, the oldest element from the list is discarded and replaced by a */
-  /* new one; a new element is added to the list otherwise.                */
-  /*                                                                       */
-  /* Note that it is possible to pre-allocate the element list nodes.      */
-  /* This is handy if `max_elements' is sufficiently small, as it saves    */
-  /* allocations/releases during the lookup process.                       */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#ifndef __FTCMRU_H__
-#define __FTCMRU_H__
-
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
-#ifdef FREETYPE_H
-#error "freetype.h of FreeType 1 has been loaded!"
-#error "Please fix the directory search order for header files"
-#error "so that freetype.h of FreeType 2 is found first."
-#endif
-
-#define  xxFT_DEBUG_ERROR
-#define  FTC_INLINE
-
-FT_BEGIN_HEADER
-
-  typedef struct FTC_MruNodeRec_*              FTC_MruNode;
-
-  typedef struct FTC_MruNodeRec_
-  {
-    FTC_MruNode   next;
-    FTC_MruNode   prev;
-
-  } FTC_MruNodeRec;
-
-  FT_EXPORT( void )
-  FTC_MruNode_Prepend( FTC_MruNode  *plist,
-                       FTC_MruNode   node );
-
-  FT_EXPORT( void )
-  FTC_MruNode_Up( FTC_MruNode  *plist,
-                  FTC_MruNode   node );
-
-  FT_EXPORT( void )
-  FTC_MruNode_Remove( FTC_MruNode  *plist,
-                      FTC_MruNode   node );
-
-  typedef struct FTC_MruListRec_*              FTC_MruList;
-
-  typedef struct FTC_MruListClassRec_ const *  FTC_MruListClass;
-
-  typedef FT_Int       (*FTC_MruNode_CompareFunc)( FTC_MruNode  node,
-                                                   FT_Pointer   key );
-
-  typedef FT_Error     (*FTC_MruNode_InitFunc)( FTC_MruNode  node,
-                                                FT_Pointer    key,
-                                                FT_Pointer    data );
-
-  typedef FT_Error     (*FTC_MruNode_ResetFunc)( FTC_MruNode  node,
-                                                 FT_Pointer   key,
-                                                 FT_Pointer   data );
-
-  typedef void         (*FTC_MruNode_DoneFunc)( FTC_MruNode  node,
-                                                FT_Pointer   data );
-
-  typedef struct FTC_MruListClassRec_
-  {
-    FT_UInt                   node_size;
-    FTC_MruNode_CompareFunc   node_compare;
-    FTC_MruNode_InitFunc      node_init;
-    FTC_MruNode_ResetFunc     node_reset;
-    FTC_MruNode_DoneFunc      node_done;
-
-  } FTC_MruListClassRec;
-
-  typedef struct FTC_MruListRec_
-  {
-    FT_UInt                  num_nodes;
-    FT_UInt                  max_nodes;
-    FTC_MruNode              nodes;
-    FT_Pointer               data;
-    FTC_MruListClassRec      clazz;
-    FT_Memory                memory;
-
-  } FTC_MruListRec;
-
-
-  FT_EXPORT( void )
-  FTC_MruList_Init( FTC_MruList       list,
-                    FTC_MruListClass  clazz,
-                    FT_UInt           max_nodes,
-                    FT_Pointer        data,
-                    FT_Memory         memory );
-
-  FT_EXPORT( void )
-  FTC_MruList_Reset( FTC_MruList  list );
-
-
-  FT_EXPORT( void )
-  FTC_MruList_Done( FTC_MruList  list );
-
-  FT_EXPORT( FTC_MruNode )
-  FTC_MruList_Find( FTC_MruList  list,
-                    FT_Pointer    key );
-
-  FT_EXPORT( FT_Error )
-  FTC_MruList_New( FTC_MruList    list,
-                   FT_Pointer     key,
-                   FTC_MruNode   *anode );
-
-  FT_EXPORT( FT_Error )
-  FTC_MruList_Lookup( FTC_MruList   list,
-                      FT_Pointer    key,
-                      FTC_MruNode  *pnode );
-                      
-
-  FT_EXPORT( void )
-  FTC_MruList_Remove( FTC_MruList  list,
-                      FTC_MruNode  node );
-
-  FT_EXPORT( void )
-  FTC_MruList_RemoveSelection( FTC_MruList              list,
-                               FTC_MruNode_CompareFunc  select,
-                               FT_Pointer               key );
-
-
-#ifdef FTC_INLINE
-
-#define  FTC_MRULIST_LOOKUP( list, key, node, error )                    \
-  FT_BEGIN_STMNT                                                         \
-    FTC_MruNode_CompareFunc  _compare = (list)->clazz.node_compare;      \
-    FTC_MruNode              _first, _node;                              \
-                                                                         \
-    error  = 0;                                                          \
-    _first = (list)->nodes;                                              \
-    _node  = NULL;                                                       \
-                                                                         \
-    if ( _first )                                                        \
-    {                                                                    \
-      _node = _first;                                                    \
-      do                                                                 \
-      {                                                                  \
-        if ( _compare( _node, (key) ) )                                  \
-        {                                                                \
-          *(FTC_MruNode*)&(node) = _node;                                \
-          goto _Ok;                                                      \
-        }                                                                \
-        _node = _node->next;                                             \
-      }                                                                  \
-      while ( _node != _first) ;                                         \
-    }                                                                    \
-                                                                         \
-    error = FTC_MruList_New( (list), (key), (FTC_MruNode*)&(node) );     \
-  _Ok:                                                                   \
-    ;                                                                    \
-  FT_END_STMNT
-
-#else  /* !FTC_INLINE */
-
-#define  FTC_MRULIST_LOOKUP_CMP( list, key, node, error )   \
-  error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) ) 
-
-#endif /* !FTC_INLINE */
-
-
-#define  FTC_MRULIST_LOOP( list, node )       \
-  FT_BEGIN_STMNT                              \
-    FTC_MruNode   _first = (list)->nodes;     \
-                                              \
-    if ( _first )                             \
-    {                                         \
-      FTC_MruNode  _node = _first;            \
-      do                                      \
-      {                                       \
-        *(FTC_MruNode*)&(node) = _node;
-
-
-#define  FTC_MRULIST_LOOP_END()              \
-        _node = _node->next;                 \
-      }                                      \
-      while ( _node != _first );             \
-    }                                        \
-  FT_END_STMNT
-
- /* */
-
-FT_END_HEADER
-
-
-#endif /* __FTCMRU_H__ */
-
-
-/* END */
+/***************************************************************************/
+/*                                                                         */
+/*  ftcmru.h                                                               */
+/*                                                                         */
+/*    Simple MRU list-cache (specification).                               */
+/*                                                                         */
+/*  Copyright 2000-2001, 2003 by                                           */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* An MRU is a list that cannot hold more than a certain number of       */
+  /* elements (`max_elements').  All elements in the list are sorted in    */
+  /* least-recently-used order, i.e., the `oldest' element is at the tail  */
+  /* of the list.                                                          */
+  /*                                                                       */
+  /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'),   */
+  /* the list is searched for an element with the corresponding key.  If   */
+  /* it is found, the element is moved to the head of the list and is      */
+  /* returned.                                                             */
+  /*                                                                       */
+  /* If no corresponding element is found, the lookup routine will try to  */
+  /* obtain a new element with the relevant key.  If the list is already   */
+  /* full, the oldest element from the list is discarded and replaced by a */
+  /* new one; a new element is added to the list otherwise.                */
+  /*                                                                       */
+  /* Note that it is possible to pre-allocate the element list nodes.      */
+  /* This is handy if `max_elements' is sufficiently small, as it saves    */
+  /* allocations/releases during the lookup process.                       */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef __FTCMRU_H__
+#define __FTCMRU_H__
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#ifdef FREETYPE_H
+#error "freetype.h of FreeType 1 has been loaded!"
+#error "Please fix the directory search order for header files"
+#error "so that freetype.h of FreeType 2 is found first."
+#endif
+
+#define  xxFT_DEBUG_ERROR
+#define  FTC_INLINE
+
+FT_BEGIN_HEADER
+
+  typedef struct FTC_MruNodeRec_*              FTC_MruNode;
+
+  typedef struct FTC_MruNodeRec_
+  {
+    FTC_MruNode   next;
+    FTC_MruNode   prev;
+
+  } FTC_MruNodeRec;
+
+  FT_EXPORT( void )
+  FTC_MruNode_Prepend( FTC_MruNode  *plist,
+                       FTC_MruNode   node );
+
+  FT_EXPORT( void )
+  FTC_MruNode_Up( FTC_MruNode  *plist,
+                  FTC_MruNode   node );
+
+  FT_EXPORT( void )
+  FTC_MruNode_Remove( FTC_MruNode  *plist,
+                      FTC_MruNode   node );
+
+  typedef struct FTC_MruListRec_*              FTC_MruList;
+
+  typedef struct FTC_MruListClassRec_ const *  FTC_MruListClass;
+
+  typedef FT_Int       (*FTC_MruNode_CompareFunc)( FTC_MruNode  node,
+                                                   FT_Pointer   key );
+
+  typedef FT_Error     (*FTC_MruNode_InitFunc)( FTC_MruNode  node,
+                                                FT_Pointer    key,
+                                                FT_Pointer    data );
+
+  typedef FT_Error     (*FTC_MruNode_ResetFunc)( FTC_MruNode  node,
+                                                 FT_Pointer   key,
+                                                 FT_Pointer   data );
+
+  typedef void         (*FTC_MruNode_DoneFunc)( FTC_MruNode  node,
+                                                FT_Pointer   data );
+
+  typedef struct FTC_MruListClassRec_
+  {
+    FT_UInt                   node_size;
+    FTC_MruNode_CompareFunc   node_compare;
+    FTC_MruNode_InitFunc      node_init;
+    FTC_MruNode_ResetFunc     node_reset;
+    FTC_MruNode_DoneFunc      node_done;
+
+  } FTC_MruListClassRec;
+
+  typedef struct FTC_MruListRec_
+  {
+    FT_UInt                  num_nodes;
+    FT_UInt                  max_nodes;
+    FTC_MruNode              nodes;
+    FT_Pointer               data;
+    FTC_MruListClassRec      clazz;
+    FT_Memory                memory;
+
+  } FTC_MruListRec;
+
+
+  FT_EXPORT( void )
+  FTC_MruList_Init( FTC_MruList       list,
+                    FTC_MruListClass  clazz,
+                    FT_UInt           max_nodes,
+                    FT_Pointer        data,
+                    FT_Memory         memory );
+
+  FT_EXPORT( void )
+  FTC_MruList_Reset( FTC_MruList  list );
+
+
+  FT_EXPORT( void )
+  FTC_MruList_Done( FTC_MruList  list );
+
+  FT_EXPORT( FTC_MruNode )
+  FTC_MruList_Find( FTC_MruList  list,
+                    FT_Pointer    key );
+
+  FT_EXPORT( FT_Error )
+  FTC_MruList_New( FTC_MruList    list,
+                   FT_Pointer     key,
+                   FTC_MruNode   *anode );
+
+  FT_EXPORT( FT_Error )
+  FTC_MruList_Lookup( FTC_MruList   list,
+                      FT_Pointer    key,
+                      FTC_MruNode  *pnode );
+                      
+
+  FT_EXPORT( void )
+  FTC_MruList_Remove( FTC_MruList  list,
+                      FTC_MruNode  node );
+
+  FT_EXPORT( void )
+  FTC_MruList_RemoveSelection( FTC_MruList              list,
+                               FTC_MruNode_CompareFunc  select,
+                               FT_Pointer               key );
+
+
+#ifdef FTC_INLINE
+
+#define  FTC_MRULIST_LOOKUP( list, key, node, error )                    \
+  FT_BEGIN_STMNT                                                         \
+    FTC_MruNode_CompareFunc  _compare = (list)->clazz.node_compare;      \
+    FTC_MruNode              _first, _node;                              \
+                                                                         \
+    error  = 0;                                                          \
+    _first = (list)->nodes;                                              \
+    _node  = NULL;                                                       \
+                                                                         \
+    if ( _first )                                                        \
+    {                                                                    \
+      _node = _first;                                                    \
+      do                                                                 \
+      {                                                                  \
+        if ( _compare( _node, (key) ) )                                  \
+        {                                                                \
+          *(FTC_MruNode*)&(node) = _node;                                \
+          goto _Ok;                                                      \
+        }                                                                \
+        _node = _node->next;                                             \
+      }                                                                  \
+      while ( _node != _first) ;                                         \
+    }                                                                    \
+                                                                         \
+    error = FTC_MruList_New( (list), (key), (FTC_MruNode*)&(node) );     \
+  _Ok:                                                                   \
+    ;                                                                    \
+  FT_END_STMNT
+
+#else  /* !FTC_INLINE */
+
+#define  FTC_MRULIST_LOOKUP_CMP( list, key, node, error )   \
+  error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) ) 
+
+#endif /* !FTC_INLINE */
+
+
+#define  FTC_MRULIST_LOOP( list, node )       \
+  FT_BEGIN_STMNT                              \
+    FTC_MruNode   _first = (list)->nodes;     \
+                                              \
+    if ( _first )                             \
+    {                                         \
+      FTC_MruNode  _node = _first;            \
+      do                                      \
+      {                                       \
+        *(FTC_MruNode*)&(node) = _node;
+
+
+#define  FTC_MRULIST_LOOP_END()              \
+        _node = _node->next;                 \
+      }                                      \
+      while ( _node != _first );             \
+    }                                        \
+  FT_END_STMNT
+
+ /* */
+
+FT_END_HEADER
+
+
+#endif /* __FTCMRU_H__ */
+
+
+/* END */
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -591,7 +591,7 @@
   /*   values as well.                                                     */
   /*                                                                       */
   /*   FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap   */
-  /*   is not Unicode or ISO-8859-1 (otherwise it is set to                */
+  /*   is neither Unicode nor ISO-8859-1 (otherwise it is set to           */
   /*   FT_ENCODING_UNICODE).  Use `FT_Get_BDF_Charset_ID' to find out      */
   /*   which encoding is really present.  If, for example, the             */
   /*   `cs_registry' field is `KOI8' and the `cs_encoding' field is `R',   */
--- a/include/freetype/fttypes.h
+++ b/include/freetype/fttypes.h
@@ -1,558 +1,558 @@
-/***************************************************************************/
-/*                                                                         */
-/*  fttypes.h                                                              */
-/*                                                                         */
-/*    FreeType simple types definitions (specification only).              */
-/*                                                                         */
-/*  Copyright 1996-2001 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-#ifndef __FTTYPES_H__
-#define __FTTYPES_H__
-
-
-#include <ft2build.h>
-#include FT_CONFIG_CONFIG_H
-#include FT_SYSTEM_H
-#include FT_IMAGE_H
-
-#include <stddef.h>
-
-
-FT_BEGIN_HEADER
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Section>                                                             */
-  /*    basic_types                                                        */
-  /*                                                                       */
-  /* <Title>                                                               */
-  /*    Basic Data Types                                                   */
-  /*                                                                       */
-  /* <Abstract>                                                            */
-  /*    The basic data types defined by the library.                       */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    This section contains the basic data types defined by FreeType 2,  */
-  /*    ranging from simple scalar types to bitmap descriptors.  More      */
-  /*    font-specific structures are defined in a different section.       */
-  /*                                                                       */
-  /* <Order>                                                               */
-  /*    FT_Byte                                                            */
-  /*    FT_Char                                                            */
-  /*    FT_Int                                                             */
-  /*    FT_UInt                                                            */
-  /*    FT_Short                                                           */
-  /*    FT_UShort                                                          */
-  /*    FT_Long                                                            */
-  /*    FT_ULong                                                           */
-  /*    FT_Bool                                                            */
-  /*    FT_Offset                                                          */
-  /*    FT_PtrDist                                                         */
-  /*    FT_String                                                          */
-  /*    FT_Error                                                           */
-  /*    FT_Fixed                                                           */
-  /*    FT_Pointer                                                         */
-  /*    FT_Pos                                                             */
-  /*    FT_Vector                                                          */
-  /*    FT_BBox                                                            */
-  /*    FT_Matrix                                                          */
-  /*    FT_FWord                                                           */
-  /*    FT_UFWord                                                          */
-  /*    FT_F2Dot14                                                         */
-  /*    FT_UnitVector                                                      */
-  /*    FT_F26Dot6                                                         */
-  /*                                                                       */
-  /*                                                                       */
-  /*    FT_Generic                                                         */
-  /*    FT_Generic_Finalizer                                               */
-  /*                                                                       */
-  /*    FT_Bitmap                                                          */
-  /*    FT_Pixel_Mode                                                      */
-  /*    FT_Palette_Mode                                                    */
-  /*    FT_Glyph_Format                                                    */
-  /*    FT_IMAGE_TAG                                                       */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Bool                                                            */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef of unsigned char, used for simple booleans.              */
-  /*                                                                       */
-  typedef unsigned char  FT_Bool;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_FWord                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A signed 16-bit integer used to store a distance in original font  */
-  /*    units.                                                             */
-  /*                                                                       */
-  typedef signed short  FT_FWord;   /* distance in FUnits */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_UFWord                                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    An unsigned 16-bit integer used to store a distance in original    */
-  /*    font units.                                                        */
-  /*                                                                       */
-  typedef unsigned short  FT_UFWord;  /* unsigned distance */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Char                                                            */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A simple typedef for the _signed_ char type.                       */
-  /*                                                                       */
-  typedef signed char  FT_Char;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Byte                                                            */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A simple typedef for the _unsigned_ char type.                     */
-  /*                                                                       */
-  typedef unsigned char  FT_Byte;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_String                                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A simple typedef for the char type, usually used for strings.      */
-  /*                                                                       */
-  typedef char  FT_String;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Short                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for signed short.                                        */
-  /*                                                                       */
-  typedef signed short  FT_Short;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_UShort                                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for unsigned short.                                      */
-  /*                                                                       */
-  typedef unsigned short  FT_UShort;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Int                                                             */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for the int type.                                        */
-  /*                                                                       */
-  typedef int  FT_Int;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_UInt                                                            */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for the unsigned int type.                               */
-  /*                                                                       */
-  typedef unsigned int  FT_UInt;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Long                                                            */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for signed long.                                         */
-  /*                                                                       */
-  typedef signed long  FT_Long;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_ULong                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for unsigned long.                                       */
-  /*                                                                       */
-  typedef unsigned long  FT_ULong;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_F2Dot14                                                         */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A signed 2.14 fixed float type used for unit vectors.              */
-  /*                                                                       */
-  typedef signed short  FT_F2Dot14;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_F26Dot6                                                         */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A signed 26.6 fixed float type used for vectorial pixel            */
-  /*    coordinates.                                                       */
-  /*                                                                       */
-  typedef signed long  FT_F26Dot6;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Fixed                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    This type is used to store 16.16 fixed float values, like scales   */
-  /*    or matrix coefficients.                                            */
-  /*                                                                       */
-  typedef signed long  FT_Fixed;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Error                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    The FreeType error code type.  A value of 0 is always interpreted  */
-  /*    as a successful operation.                                         */
-  /*                                                                       */
-  typedef int  FT_Error;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Pointer                                                         */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A simple typedef for a typeless pointer.                           */
-  /*                                                                       */
-  typedef void*  FT_Pointer;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Offset                                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    This is equivalent to the ANSI C `size_t' type, i.e. the largest   */
-  /*    _unsigned_ integer type used to express a file size or position,   */
-  /*    or a memory block size.                                            */
-  /*                                                                       */
-  typedef size_t  FT_Offset;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_PtrDist                                                         */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    This is equivalent to the ANSI C `ptrdiff_t' type, i.e. the        */
-  /*    largest _signed_ integer type used to express the distance         */
-  /*    between two pointers.                                              */
-  /*                                                                       */
-  typedef size_t  FT_PtrDist;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Struct>                                                              */
-  /*    FT_UnitVector                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A simple structure used to store a 2D vector unit vector.  Uses    */
-  /*    FT_F2Dot14 types.                                                  */
-  /*                                                                       */
-  /* <Fields>                                                              */
-  /*    x :: Horizontal coordinate.                                        */
-  /*                                                                       */
-  /*    y :: Vertical coordinate.                                          */
-  /*                                                                       */
-  typedef struct  FT_UnitVector_
-  {
-    FT_F2Dot14  x;
-    FT_F2Dot14  y;
-
-  } FT_UnitVector;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Struct>                                                              */
-  /*    FT_Matrix                                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A simple structure used to store a 2x2 matrix.  Coefficients are   */
-  /*    in 16.16 fixed float format.  The computation performed is:        */
-  /*                                                                       */
-  /*       {                                                               */
-  /*          x' = x*xx + y*xy                                             */
-  /*          y' = x*yx + y*yy                                             */
-  /*       }                                                               */
-  /*                                                                       */
-  /* <Fields>                                                              */
-  /*    xx :: Matrix coefficient.                                          */
-  /*                                                                       */
-  /*    xy :: Matrix coefficient.                                          */
-  /*                                                                       */
-  /*    yx :: Matrix coefficient.                                          */
-  /*                                                                       */
-  /*    yy :: Matrix coefficient.                                          */
-  /*                                                                       */
-  typedef struct  FT_Matrix_
-  {
-    FT_Fixed  xx, xy;
-    FT_Fixed  yx, yy;
-
-  } FT_Matrix;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Struct>                                                              */
-  /*    FT_Data	                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Read-only binary data represented as a pointer and a length.       */
-  /*                                                                       */
-  /* <Fields>                                                              */
-  /*    pointer :: The data.                                               */
-  /*                                                                       */
-  /*    length  :: The length of the data in bytes.                        */
-  /*                                                                       */
-  typedef struct  FT_Data_
-  {
-    const FT_Byte*  pointer;
-    FT_Int          length;
-
-  } FT_Data;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <FuncType>                                                            */
-  /*    FT_Generic_Finalizer                                               */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Describes a function used to destroy the `client' data of any      */
-  /*    FreeType object.  See the description of the FT_Generic type for   */
-  /*    details of usage.                                                  */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    The address of the FreeType object which is under finalization.    */
-  /*    Its client data is accessed through its `generic' field.           */
-  /*                                                                       */
-  typedef void  (*FT_Generic_Finalizer)(void*  object);
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Struct>                                                              */
-  /*    FT_Generic                                                         */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Client applications often need to associate their own data to a    */
-  /*    variety of FreeType core objects.  For example, a text layout API  */
-  /*    might want to associate a glyph cache to a given size object.      */
-  /*                                                                       */
-  /*    Most FreeType object contains a `generic' field, of type           */
-  /*    FT_Generic, which usage is left to client applications and font    */
-  /*    servers.                                                           */
-  /*                                                                       */
-  /*    It can be used to store a pointer to client-specific data, as well */
-  /*    as the address of a `finalizer' function, which will be called by  */
-  /*    FreeType when the object is destroyed (for example, the previous   */
-  /*    client example would put the address of the glyph cache destructor */
-  /*    in the `finalizer' field).                                         */
-  /*                                                                       */
-  /* <Fields>                                                              */
-  /*    data      :: A typeless pointer to any client-specified data. This */
-  /*                 field is completely ignored by the FreeType library.  */
-  /*                                                                       */
-  /*    finalizer :: A pointer to a `generic finalizer' function, which    */
-  /*                 will be called when the object is destroyed.  If this */
-  /*                 field is set to NULL, no code will be called.         */
-  /*                                                                       */
-  typedef struct  FT_Generic_
-  {
-    void*                 data;
-    FT_Generic_Finalizer  finalizer;
-
-  } FT_Generic;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Macro>                                                               */
-  /*    FT_MAKE_TAG                                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    This macro converts four letter tags which are used to label       */
-  /*    TrueType tables into an unsigned long to be used within FreeType.  */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    The produced values *must* be 32bit integers.  Don't redefine this */
-  /*    macro.                                                             */
-  /*                                                                       */
-#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
-          ( ( (FT_ULong)_x1 << 24 ) |     \
-            ( (FT_ULong)_x2 << 16 ) |     \
-            ( (FT_ULong)_x3 <<  8 ) |     \
-              (FT_ULong)_x4         )
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*                                                                       */
-  /*                    L I S T   M A N A G E M E N T                      */
-  /*                                                                       */
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Section>                                                             */
-  /*    list_processing                                                    */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_ListNode                                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*     Many elements and objects in FreeType are listed through a        */
-  /*     FT_List record (see FT_ListRec).  As its name suggests, a         */
-  /*     FT_ListNode is a handle to a single list element.                 */
-  /*                                                                       */
-  typedef struct FT_ListNodeRec_*  FT_ListNode;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_List                                                            */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A handle to a list record (see FT_ListRec).                        */
-  /*                                                                       */
-  typedef struct FT_ListRec_*  FT_List;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Struct>                                                              */
-  /*    FT_ListNodeRec                                                     */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A structure used to hold a single list element.                    */
-  /*                                                                       */
-  /* <Fields>                                                              */
-  /*    prev :: The previous element in the list.  NULL if first.          */
-  /*                                                                       */
-  /*    next :: The next element in the list.  NULL if last.               */
-  /*                                                                       */
-  /*    data :: A typeless pointer to the listed object.                   */
-  /*                                                                       */
-  typedef struct  FT_ListNodeRec_
-  {
-    FT_ListNode  prev;
-    FT_ListNode  next;
-    void*        data;
-
-  } FT_ListNodeRec;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Struct>                                                              */
-  /*    FT_ListRec                                                         */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A structure used to hold a simple doubly-linked list.  These are   */
-  /*    used in many parts of FreeType.                                    */
-  /*                                                                       */
-  /* <Fields>                                                              */
-  /*    head :: The head (first element) of doubly-linked list.            */
-  /*                                                                       */
-  /*    tail :: The tail (last element) of doubly-linked list.             */
-  /*                                                                       */
-  typedef struct  FT_ListRec_
-  {
-    FT_ListNode  head;
-    FT_ListNode  tail;
-
-  } FT_ListRec;
-
-
-  /* */
-
-#define FT_IS_EMPTY( list )  ( (list).head == 0 )
-
-  /* return base error code (without module-specific prefix) */
-#define FT_ERROR_BASE( x )    ( (x) & 0xFF )
-
-  /* return module error code */
-#define FT_ERROR_MODULE( x )  ( (x) & 0xFF00U )
-
-#define FT_BOOL( x )  ( (FT_Bool)( x ) )
-
-FT_END_HEADER
-
-#endif /* __FTTYPES_H__ */
-
-
-/* END */
+/***************************************************************************/
+/*                                                                         */
+/*  fttypes.h                                                              */
+/*                                                                         */
+/*    FreeType simple types definitions (specification only).              */
+/*                                                                         */
+/*  Copyright 1996-2001 by                                                 */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef __FTTYPES_H__
+#define __FTTYPES_H__
+
+
+#include <ft2build.h>
+#include FT_CONFIG_CONFIG_H
+#include FT_SYSTEM_H
+#include FT_IMAGE_H
+
+#include <stddef.h>
+
+
+FT_BEGIN_HEADER
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Section>                                                             */
+  /*    basic_types                                                        */
+  /*                                                                       */
+  /* <Title>                                                               */
+  /*    Basic Data Types                                                   */
+  /*                                                                       */
+  /* <Abstract>                                                            */
+  /*    The basic data types defined by the library.                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This section contains the basic data types defined by FreeType 2,  */
+  /*    ranging from simple scalar types to bitmap descriptors.  More      */
+  /*    font-specific structures are defined in a different section.       */
+  /*                                                                       */
+  /* <Order>                                                               */
+  /*    FT_Byte                                                            */
+  /*    FT_Char                                                            */
+  /*    FT_Int                                                             */
+  /*    FT_UInt                                                            */
+  /*    FT_Short                                                           */
+  /*    FT_UShort                                                          */
+  /*    FT_Long                                                            */
+  /*    FT_ULong                                                           */
+  /*    FT_Bool                                                            */
+  /*    FT_Offset                                                          */
+  /*    FT_PtrDist                                                         */
+  /*    FT_String                                                          */
+  /*    FT_Error                                                           */
+  /*    FT_Fixed                                                           */
+  /*    FT_Pointer                                                         */
+  /*    FT_Pos                                                             */
+  /*    FT_Vector                                                          */
+  /*    FT_BBox                                                            */
+  /*    FT_Matrix                                                          */
+  /*    FT_FWord                                                           */
+  /*    FT_UFWord                                                          */
+  /*    FT_F2Dot14                                                         */
+  /*    FT_UnitVector                                                      */
+  /*    FT_F26Dot6                                                         */
+  /*                                                                       */
+  /*                                                                       */
+  /*    FT_Generic                                                         */
+  /*    FT_Generic_Finalizer                                               */
+  /*                                                                       */
+  /*    FT_Bitmap                                                          */
+  /*    FT_Pixel_Mode                                                      */
+  /*    FT_Palette_Mode                                                    */
+  /*    FT_Glyph_Format                                                    */
+  /*    FT_IMAGE_TAG                                                       */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Bool                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef of unsigned char, used for simple booleans.              */
+  /*                                                                       */
+  typedef unsigned char  FT_Bool;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_FWord                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A signed 16-bit integer used to store a distance in original font  */
+  /*    units.                                                             */
+  /*                                                                       */
+  typedef signed short  FT_FWord;   /* distance in FUnits */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_UFWord                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An unsigned 16-bit integer used to store a distance in original    */
+  /*    font units.                                                        */
+  /*                                                                       */
+  typedef unsigned short  FT_UFWord;  /* unsigned distance */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Char                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple typedef for the _signed_ char type.                       */
+  /*                                                                       */
+  typedef signed char  FT_Char;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Byte                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple typedef for the _unsigned_ char type.                     */
+  /*                                                                       */
+  typedef unsigned char  FT_Byte;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_String                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple typedef for the char type, usually used for strings.      */
+  /*                                                                       */
+  typedef char  FT_String;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Short                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for signed short.                                        */
+  /*                                                                       */
+  typedef signed short  FT_Short;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_UShort                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for unsigned short.                                      */
+  /*                                                                       */
+  typedef unsigned short  FT_UShort;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Int                                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for the int type.                                        */
+  /*                                                                       */
+  typedef int  FT_Int;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_UInt                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for the unsigned int type.                               */
+  /*                                                                       */
+  typedef unsigned int  FT_UInt;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Long                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for signed long.                                         */
+  /*                                                                       */
+  typedef signed long  FT_Long;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_ULong                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for unsigned long.                                       */
+  /*                                                                       */
+  typedef unsigned long  FT_ULong;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_F2Dot14                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A signed 2.14 fixed float type used for unit vectors.              */
+  /*                                                                       */
+  typedef signed short  FT_F2Dot14;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_F26Dot6                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A signed 26.6 fixed float type used for vectorial pixel            */
+  /*    coordinates.                                                       */
+  /*                                                                       */
+  typedef signed long  FT_F26Dot6;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Fixed                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This type is used to store 16.16 fixed float values, like scales   */
+  /*    or matrix coefficients.                                            */
+  /*                                                                       */
+  typedef signed long  FT_Fixed;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Error                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The FreeType error code type.  A value of 0 is always interpreted  */
+  /*    as a successful operation.                                         */
+  /*                                                                       */
+  typedef int  FT_Error;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Pointer                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple typedef for a typeless pointer.                           */
+  /*                                                                       */
+  typedef void*  FT_Pointer;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Offset                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This is equivalent to the ANSI C `size_t' type, i.e. the largest   */
+  /*    _unsigned_ integer type used to express a file size or position,   */
+  /*    or a memory block size.                                            */
+  /*                                                                       */
+  typedef size_t  FT_Offset;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_PtrDist                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This is equivalent to the ANSI C `ptrdiff_t' type, i.e. the        */
+  /*    largest _signed_ integer type used to express the distance         */
+  /*    between two pointers.                                              */
+  /*                                                                       */
+  typedef size_t  FT_PtrDist;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_UnitVector                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure used to store a 2D vector unit vector.  Uses    */
+  /*    FT_F2Dot14 types.                                                  */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    x :: Horizontal coordinate.                                        */
+  /*                                                                       */
+  /*    y :: Vertical coordinate.                                          */
+  /*                                                                       */
+  typedef struct  FT_UnitVector_
+  {
+    FT_F2Dot14  x;
+    FT_F2Dot14  y;
+
+  } FT_UnitVector;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_Matrix                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure used to store a 2x2 matrix.  Coefficients are   */
+  /*    in 16.16 fixed float format.  The computation performed is:        */
+  /*                                                                       */
+  /*       {                                                               */
+  /*          x' = x*xx + y*xy                                             */
+  /*          y' = x*yx + y*yy                                             */
+  /*       }                                                               */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    xx :: Matrix coefficient.                                          */
+  /*                                                                       */
+  /*    xy :: Matrix coefficient.                                          */
+  /*                                                                       */
+  /*    yx :: Matrix coefficient.                                          */
+  /*                                                                       */
+  /*    yy :: Matrix coefficient.                                          */
+  /*                                                                       */
+  typedef struct  FT_Matrix_
+  {
+    FT_Fixed  xx, xy;
+    FT_Fixed  yx, yy;
+
+  } FT_Matrix;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_Data	                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Read-only binary data represented as a pointer and a length.       */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    pointer :: The data.                                               */
+  /*                                                                       */
+  /*    length  :: The length of the data in bytes.                        */
+  /*                                                                       */
+  typedef struct  FT_Data_
+  {
+    const FT_Byte*  pointer;
+    FT_Int          length;
+
+  } FT_Data;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FT_Generic_Finalizer                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Describes a function used to destroy the `client' data of any      */
+  /*    FreeType object.  See the description of the FT_Generic type for   */
+  /*    details of usage.                                                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    The address of the FreeType object which is under finalization.    */
+  /*    Its client data is accessed through its `generic' field.           */
+  /*                                                                       */
+  typedef void  (*FT_Generic_Finalizer)(void*  object);
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_Generic                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Client applications often need to associate their own data to a    */
+  /*    variety of FreeType core objects.  For example, a text layout API  */
+  /*    might want to associate a glyph cache to a given size object.      */
+  /*                                                                       */
+  /*    Most FreeType object contains a `generic' field, of type           */
+  /*    FT_Generic, which usage is left to client applications and font    */
+  /*    servers.                                                           */
+  /*                                                                       */
+  /*    It can be used to store a pointer to client-specific data, as well */
+  /*    as the address of a `finalizer' function, which will be called by  */
+  /*    FreeType when the object is destroyed (for example, the previous   */
+  /*    client example would put the address of the glyph cache destructor */
+  /*    in the `finalizer' field).                                         */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    data      :: A typeless pointer to any client-specified data. This */
+  /*                 field is completely ignored by the FreeType library.  */
+  /*                                                                       */
+  /*    finalizer :: A pointer to a `generic finalizer' function, which    */
+  /*                 will be called when the object is destroyed.  If this */
+  /*                 field is set to NULL, no code will be called.         */
+  /*                                                                       */
+  typedef struct  FT_Generic_
+  {
+    void*                 data;
+    FT_Generic_Finalizer  finalizer;
+
+  } FT_Generic;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Macro>                                                               */
+  /*    FT_MAKE_TAG                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This macro converts four letter tags which are used to label       */
+  /*    TrueType tables into an unsigned long to be used within FreeType.  */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The produced values *must* be 32bit integers.  Don't redefine this */
+  /*    macro.                                                             */
+  /*                                                                       */
+#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
+          ( ( (FT_ULong)_x1 << 24 ) |     \
+            ( (FT_ULong)_x2 << 16 ) |     \
+            ( (FT_ULong)_x3 <<  8 ) |     \
+              (FT_ULong)_x4         )
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*                                                                       */
+  /*                    L I S T   M A N A G E M E N T                      */
+  /*                                                                       */
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Section>                                                             */
+  /*    list_processing                                                    */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_ListNode                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*     Many elements and objects in FreeType are listed through a        */
+  /*     FT_List record (see FT_ListRec).  As its name suggests, a         */
+  /*     FT_ListNode is a handle to a single list element.                 */
+  /*                                                                       */
+  typedef struct FT_ListNodeRec_*  FT_ListNode;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_List                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a list record (see FT_ListRec).                        */
+  /*                                                                       */
+  typedef struct FT_ListRec_*  FT_List;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_ListNodeRec                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to hold a single list element.                    */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    prev :: The previous element in the list.  NULL if first.          */
+  /*                                                                       */
+  /*    next :: The next element in the list.  NULL if last.               */
+  /*                                                                       */
+  /*    data :: A typeless pointer to the listed object.                   */
+  /*                                                                       */
+  typedef struct  FT_ListNodeRec_
+  {
+    FT_ListNode  prev;
+    FT_ListNode  next;
+    void*        data;
+
+  } FT_ListNodeRec;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_ListRec                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to hold a simple doubly-linked list.  These are   */
+  /*    used in many parts of FreeType.                                    */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    head :: The head (first element) of doubly-linked list.            */
+  /*                                                                       */
+  /*    tail :: The tail (last element) of doubly-linked list.             */
+  /*                                                                       */
+  typedef struct  FT_ListRec_
+  {
+    FT_ListNode  head;
+    FT_ListNode  tail;
+
+  } FT_ListRec;
+
+
+  /* */
+
+#define FT_IS_EMPTY( list )  ( (list).head == 0 )
+
+  /* return base error code (without module-specific prefix) */
+#define FT_ERROR_BASE( x )    ( (x) & 0xFF )
+
+  /* return module error code */
+#define FT_ERROR_MODULE( x )  ( (x) & 0xFF00U )
+
+#define FT_BOOL( x )  ( (FT_Bool)( x ) )
+
+FT_END_HEADER
+
+#endif /* __FTTYPES_H__ */
+
+
+/* END */
--- a/include/freetype/ftwinfnt.h
+++ b/include/freetype/ftwinfnt.h
@@ -59,7 +59,8 @@
    *   A list of valid values for the `charset' byte in
    *   @FT_WinFNT_HeaderRec.  Exact mapping tables for the various cpXXXX
    *   encodings (except for cp1361) can be found at ftp://ftp.unicode.org
-   *   in the MAPPINGS/VENDORS/MICSFT/WINDOWS subdirectory.
+   *   in the MAPPINGS/VENDORS/MICSFT/WINDOWS subdirectory.  cp1361 is
+   *   roughly a superset of MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT.
    *
    * @values:
    *   FT_WinFNT_ID_DEFAULT ::
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -78,13 +78,15 @@
 #define ABS( a )     ( (a) < 0 ? -(a) : (a) )
 #endif
 
-#define  FT_PAD_FLOOR( x, n )    ( (x) & ~((n)-1) )
-#define  FT_PAD_ROUND( x, n )    FT_PAD_FLOOR( (x)+((n)/2), n )
-#define  FT_PAD_CEIL( x, n )     FT_PAD_FLOOR( (x)+((n)-1), n )
 
-#define  FT_PIX_FLOOR( x )      ( (x) & ~63 )
-#define  FT_PIX_ROUND( x )      FT_PIX_FLOOR( (x)+32 )
-#define  FT_PIX_CEIL( x )       FT_PIX_FLOOR( (x)+63 )
+#define FT_PAD_FLOOR( x, n )  ( (x) & ~((n)-1) )
+#define FT_PAD_ROUND( x, n )  FT_PAD_FLOOR( (x) + ((n)/2), n )
+#define FT_PAD_CEIL( x, n )   FT_PAD_FLOOR( (x) + ((n)-1), n )
+
+#define FT_PIX_FLOOR( x )     ( (x) & ~63 )
+#define FT_PIX_ROUND( x )     FT_PIX_FLOOR( (x) + 32 )
+#define FT_PIX_CEIL( x )      FT_PIX_FLOOR( (x) + 63 )
+
 
   /*************************************************************************/
   /*************************************************************************/
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -1978,16 +1978,16 @@
     /* Compute root ascender, descender, test height, and max_advance */
 
     metrics->ascender    = FT_PIX_CEIL( FT_MulFix( face->ascender,
-                                                       metrics->y_scale ) );
+                                                   metrics->y_scale ) );
 
     metrics->descender   = FT_PIX_FLOOR( FT_MulFix( face->descender,
-                                                       metrics->y_scale ) );
+                                                    metrics->y_scale ) );
 
     metrics->height      = FT_PIX_ROUND( FT_MulFix( face->height,
-                                                         metrics->y_scale ) );
+                                                    metrics->y_scale ) );
 
     metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->max_advance_width,
-                                                       metrics->x_scale ) );
+                                                    metrics->x_scale ) );
   }
 
 
--- a/src/base/ftsynth.c
+++ b/src/base/ftsynth.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType synthesizing code for emboldening and slanting (body).      */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002 by                                           */
+/*  Copyright 2000-2001, 2002, 2003 by                                     */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -279,7 +279,8 @@
       first = last + 1;
     }
 
-    slot->metrics.horiAdvance = ( slot->metrics.horiAdvance + distance*4 ) & ~63;
+    slot->metrics.horiAdvance =
+      ( slot->metrics.horiAdvance + distance*4 ) & ~63;
   }
 
 
--- a/src/cache/ftcbasic.c
+++ b/src/cache/ftcbasic.c
@@ -1,393 +1,393 @@
-#include <ft2build.h>
-#include FT_CACHE_H
-#include FT_CACHE_INTERNAL_GLYPH_H
-#include FT_CACHE_INTERNAL_IMAGE_H
-#include FT_CACHE_INTERNAL_SBITS_H
-#include FT_INTERNAL_MEMORY_H
-
-#include "ftcerror.h"
-
-
- /*
-  *  Basic Families
-  *
-  *
-  */
-  typedef struct FTC_BasicAttrRec_
-  {
-    FTC_ScalerRec  scaler;
-    FT_UInt        load_flags;
-
-  } FTC_BasicAttrRec, *FTC_BasicAttrs;
-
-#define  FTC_BASIC_ATTR_COMPARE(a,b)                           \
-       ( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) &&   \
-         (a)->load_flags == (b)->load_flags                )
-
-#define  FTC_BASIC_ATTR_HASH(a)   \
-       ( FTC_SCALER_HASH(&(a)->scaler) + 31*(a)->load_flags )
-
-
-  typedef struct FTC_BasicQueryRec_
-  {
-    FTC_GQueryRec      gquery;
-    FTC_BasicAttrRec   attrs;
-
-  } FTC_BasicQueryRec, *FTC_BasicQuery;
-
-
-
-  typedef struct FTC_BasicFamilyRec_
-  {
-    FTC_FamilyRec      family;
-    FTC_BasicAttrRec   attrs;
-
-  } FTC_BasicFamilyRec, *FTC_BasicFamily;
-
-
-  static FT_Bool
-  ftc_basic_family_compare( FTC_BasicFamily   family,
-                            FTC_BasicQuery    query )
-  {
-    return FT_BOOL( FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs ) );
-  }
-
-  static FT_Error
-  ftc_basic_family_init( FTC_BasicFamily   family,
-                         FTC_BasicQuery    query,
-                         FTC_Cache         cache )
-  {
-    FTC_Family_Init( FTC_FAMILY( family ), cache );
-    family->attrs = query->attrs;
-    return 0;
-  }
-
-
-  static FT_UInt
-  ftc_basic_family_get_count( FTC_BasicFamily  family,
-                              FTC_Manager      manager )
-  {
-    FT_Error  error;
-    FT_Face   face;
-    FT_UInt   result = 0;
-
-    error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id,
-                                    &face );
-    if ( !error )
-      result = face->num_glyphs;
-
-    return result;
-  }
-
-
-  static FT_Error
-  ftc_basic_family_load_bitmap( FTC_BasicFamily  family,
-                                FT_UInt          gindex,
-                                FTC_Manager      manager,
-                                FT_Face         *aface )
-  {
-    FT_Error  error;
-    FT_Size   size;
-
-    error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size );
-    if ( !error )
-    {
-      FT_Face   face = size->face;
-
-      error = FT_Load_Glyph( face, gindex, family->attrs.load_flags |
-                                           FT_LOAD_RENDER );
-      if ( !error )
-        *aface = face;
-    }
-    return error;
-  }
-
-
-  static FT_Error
-  ftc_basic_family_load_glyph( FTC_BasicFamily  family,
-                               FT_UInt          gindex,
-                               FTC_Cache        cache,
-                               FT_Glyph        *aglyph )
-  {
-    FT_Error       error;
-    FTC_Scaler     scaler = &family->attrs.scaler;
-    FT_Face        face;
-    FT_Size        size;
-
-    /* we will now load the glyph image */
-    error = FTC_Manager_LookupSize( cache->manager,
-                                    scaler,
-                                    &size );
-    if ( !error )
-    {
-      face = size->face;
-
-      error = FT_Load_Glyph( face, gindex, family->attrs.load_flags );
-      if ( !error )
-      {
-        if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP  ||
-             face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
-        {
-          /* ok, copy it */
-          FT_Glyph  glyph;
-
-
-          error = FT_Get_Glyph( face->glyph, &glyph );
-          if ( !error )
-          {
-            *aglyph = glyph;
-            goto Exit;
-          }
-        }
-        else
-          error = FTC_Err_Invalid_Argument;
-      }
-    }
-  Exit:
-    return error;
-  }
-
-
-  static FT_Bool
-  ftc_basic_gnode_compare_faceid( FTC_GNode   gnode,
-                                  FTC_FaceID  face_id,
-                                  FTC_Cache   cache )
-  {
-    FTC_BasicFamily  family = (FTC_BasicFamily) gnode->family;
-    FT_Bool          result;
-
-    result = FT_BOOL( family->attrs.scaler.face_id == face_id );
-    if ( result )
-    {
-     /* we must call this function to avoid this node from appearing
-      * in later lookups with the same face_id !!
-      */
-      FTC_GNode_UnselectFamily( gnode, cache );
-    }
-    return result;
-  }
-
-
-
- /*
-  *
-  * basic image cache
-  *
-  */
-
-  static const FTC_IFamilyClassRec  ftc_basic_image_family_class =
-  {
-    {
-      sizeof( FTC_BasicFamilyRec ),
-      (FTC_MruNode_CompareFunc)  ftc_basic_family_compare,
-      (FTC_MruNode_InitFunc)     ftc_basic_family_init,
-      (FTC_MruNode_ResetFunc)    NULL,
-      (FTC_MruNode_DoneFunc)     NULL
-    },
-    (FTC_IFamily_LoadGlyphFunc)  ftc_basic_family_load_glyph
-  };
-
-
-
-  static const FTC_GCacheClassRec  ftc_basic_image_cache_class =
-  {
-    {
-      (FTC_Node_NewFunc)      FTC_INode_New,
-      (FTC_Node_WeightFunc)   FTC_INode_Weight,
-      (FTC_Node_CompareFunc)  FTC_GNode_Compare,
-      (FTC_Node_CompareFunc)  ftc_basic_gnode_compare_faceid,
-      (FTC_Node_FreeFunc)     FTC_INode_Free,
-
-      sizeof( FTC_GCacheRec ),
-      (FTC_Cache_InitFunc)    FTC_GCache_Init,
-      (FTC_Cache_DoneFunc)    FTC_GCache_Done
-    },
-    (FTC_MruListClass) & ftc_basic_image_family_class
-  };
-
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_ImageCache_New( FTC_Manager      manager,
-                      FTC_ImageCache  *acache )
-  {
-    return FTC_GCache_New( manager, & ftc_basic_image_cache_class,
-                           (FTC_GCache*) acache );
-  }
-
-
-  /* documentation is in ftcimage.h */
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_ImageCache_Lookup( FTC_ImageCache  cache,
-                         FTC_ImageType   type,
-                         FT_UInt         gindex,
-                         FT_Glyph       *aglyph,
-                         FTC_Node       *anode )
-  {
-    FTC_BasicQueryRec  query;
-    FTC_INode          node;
-    FT_Error           error;
-    FT_UInt32          hash;
-
-
-    /* some argument checks are delayed to FTC_Cache_Lookup */
-    if ( !aglyph )
-    {
-      error = FTC_Err_Invalid_Argument;
-      goto Exit;
-    }
-
-    *aglyph = NULL;
-    if ( anode )
-      *anode  = NULL;
-
-    query.attrs.scaler.face_id = type->face_id;
-    query.attrs.scaler.width   = type->width;
-    query.attrs.scaler.height  = type->height;
-    query.attrs.scaler.pixel   = 1;
-    query.attrs.load_flags     = type->flags;
-
-    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;
-    
-#if 1  /* inlining is about 50% faster !! */ 
-    FTC_GCACHE_LOOKUP_CMP( cache,
-                           ftc_basic_family_compare,
-                           FTC_GNode_Compare,
-                           hash, gindex,
-                           &query,
-                           node,
-                           error );
-#else
-    error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
-                               hash, gindex,
-                               FTC_GQUERY( &query ),
-                               (FTC_Node*) &node );
-#endif
-    if ( !error )
-    {
-      *aglyph = FTC_INODE(node)->glyph;
-
-      if ( anode )
-      {
-        *anode = FTC_NODE(node);
-        FTC_NODE(node)->ref_count++;
-      }
-    }
-
-  Exit:
-    return error;
-  }
-
-
-
- /*
-  *
-  * basic small bitmap cache
-  *
-  */
-
-
-  static const FTC_SFamilyClassRec  ftc_basic_sbit_family_class =
-  {
-    {
-      sizeof( FTC_BasicFamilyRec ),
-      (FTC_MruNode_CompareFunc)  ftc_basic_family_compare,
-      (FTC_MruNode_InitFunc)     ftc_basic_family_init,
-      (FTC_MruNode_ResetFunc)    NULL,
-      (FTC_MruNode_DoneFunc)     NULL
-    },
-    (FTC_SFamily_GetCountFunc)   ftc_basic_family_get_count,
-    (FTC_SFamily_LoadGlyphFunc)  ftc_basic_family_load_bitmap
-  };
-
-
-  static const FTC_GCacheClassRec  ftc_basic_sbit_cache_class =
-  {
-    {
-      (FTC_Node_NewFunc)      FTC_SNode_New,
-      (FTC_Node_WeightFunc)   FTC_SNode_Weight,
-      (FTC_Node_CompareFunc)  FTC_SNode_Compare,
-      (FTC_Node_CompareFunc)  ftc_basic_gnode_compare_faceid,
-      (FTC_Node_FreeFunc)     FTC_SNode_Free,
-
-      sizeof( FTC_GCacheRec ),
-      (FTC_Cache_InitFunc)    FTC_GCache_Init,
-      (FTC_Cache_DoneFunc)    FTC_GCache_Done
-    },
-    (FTC_MruListClass) & ftc_basic_sbit_family_class
-  };
-
-
-
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_SBitCache_New( FTC_Manager     manager,
-                     FTC_SBitCache  *acache )
-  {
-    return FTC_GCache_New( manager, & ftc_basic_sbit_cache_class,
-                           (FTC_GCache*) acache );
-  }
-
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_SBitCache_Lookup( FTC_SBitCache   cache,
-                        FTC_ImageType   type,
-                        FT_UInt         gindex,
-                        FTC_SBit       *ansbit,
-                        FTC_Node       *anode )
-  {
-    FT_Error           error;
-    FTC_BasicQueryRec  query;
-    FTC_SNode          node;
-    FT_UInt32          hash;
-
-    if ( anode )
-      *anode = NULL;
-
-    /* other argument checks delayed to FTC_Cache_Lookup */
-    if ( !ansbit )
-      return FTC_Err_Invalid_Argument;
-
-    *ansbit = NULL;
-
-    query.attrs.scaler.face_id = type->face_id;
-    query.attrs.scaler.width   = type->width;
-    query.attrs.scaler.height  = type->height;
-    query.attrs.scaler.pixel   = 1;
-    query.attrs.load_flags     = type->flags;
-
-   /* beware, the hash must be the same for all glyph ranges !!
-    */
-    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
-           (gindex/FTC_SBIT_ITEMS_PER_NODE);
-
-#if 1  /* inlining is about 50% faster !! */ 
-    FTC_GCACHE_LOOKUP_CMP( cache,
-                           ftc_basic_family_compare,
-                           FTC_SNode_Compare,
-                           hash, gindex,
-                           &query,
-                           node,
-                           error );
-#else
-    error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
-                               hash,
-                               gindex,
-                               FTC_GQUERY( &query ),
-                               (FTC_Node*) &node );
-#endif                               
-    if ( error )
-      goto Exit;
-
-    *ansbit = node->sbits + ( gindex - FTC_GNODE(node)->gindex );
-
-    if ( anode )
-    {
-      *anode = FTC_NODE( node );
-      FTC_NODE( node )->ref_count++;
-    }
-
-  Exit:
-    return error;
-  }
-
+#include <ft2build.h>
+#include FT_CACHE_H
+#include FT_CACHE_INTERNAL_GLYPH_H
+#include FT_CACHE_INTERNAL_IMAGE_H
+#include FT_CACHE_INTERNAL_SBITS_H
+#include FT_INTERNAL_MEMORY_H
+
+#include "ftcerror.h"
+
+
+ /*
+  *  Basic Families
+  *
+  *
+  */
+  typedef struct FTC_BasicAttrRec_
+  {
+    FTC_ScalerRec  scaler;
+    FT_UInt        load_flags;
+
+  } FTC_BasicAttrRec, *FTC_BasicAttrs;
+
+#define  FTC_BASIC_ATTR_COMPARE(a,b)                           \
+       ( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) &&   \
+         (a)->load_flags == (b)->load_flags                )
+
+#define  FTC_BASIC_ATTR_HASH(a)   \
+       ( FTC_SCALER_HASH(&(a)->scaler) + 31*(a)->load_flags )
+
+
+  typedef struct FTC_BasicQueryRec_
+  {
+    FTC_GQueryRec      gquery;
+    FTC_BasicAttrRec   attrs;
+
+  } FTC_BasicQueryRec, *FTC_BasicQuery;
+
+
+
+  typedef struct FTC_BasicFamilyRec_
+  {
+    FTC_FamilyRec      family;
+    FTC_BasicAttrRec   attrs;
+
+  } FTC_BasicFamilyRec, *FTC_BasicFamily;
+
+
+  static FT_Bool
+  ftc_basic_family_compare( FTC_BasicFamily   family,
+                            FTC_BasicQuery    query )
+  {
+    return FT_BOOL( FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs ) );
+  }
+
+  static FT_Error
+  ftc_basic_family_init( FTC_BasicFamily   family,
+                         FTC_BasicQuery    query,
+                         FTC_Cache         cache )
+  {
+    FTC_Family_Init( FTC_FAMILY( family ), cache );
+    family->attrs = query->attrs;
+    return 0;
+  }
+
+
+  static FT_UInt
+  ftc_basic_family_get_count( FTC_BasicFamily  family,
+                              FTC_Manager      manager )
+  {
+    FT_Error  error;
+    FT_Face   face;
+    FT_UInt   result = 0;
+
+    error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id,
+                                    &face );
+    if ( !error )
+      result = face->num_glyphs;
+
+    return result;
+  }
+
+
+  static FT_Error
+  ftc_basic_family_load_bitmap( FTC_BasicFamily  family,
+                                FT_UInt          gindex,
+                                FTC_Manager      manager,
+                                FT_Face         *aface )
+  {
+    FT_Error  error;
+    FT_Size   size;
+
+    error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size );
+    if ( !error )
+    {
+      FT_Face   face = size->face;
+
+      error = FT_Load_Glyph( face, gindex, family->attrs.load_flags |
+                                           FT_LOAD_RENDER );
+      if ( !error )
+        *aface = face;
+    }
+    return error;
+  }
+
+
+  static FT_Error
+  ftc_basic_family_load_glyph( FTC_BasicFamily  family,
+                               FT_UInt          gindex,
+                               FTC_Cache        cache,
+                               FT_Glyph        *aglyph )
+  {
+    FT_Error       error;
+    FTC_Scaler     scaler = &family->attrs.scaler;
+    FT_Face        face;
+    FT_Size        size;
+
+    /* we will now load the glyph image */
+    error = FTC_Manager_LookupSize( cache->manager,
+                                    scaler,
+                                    &size );
+    if ( !error )
+    {
+      face = size->face;
+
+      error = FT_Load_Glyph( face, gindex, family->attrs.load_flags );
+      if ( !error )
+      {
+        if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP  ||
+             face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
+        {
+          /* ok, copy it */
+          FT_Glyph  glyph;
+
+
+          error = FT_Get_Glyph( face->glyph, &glyph );
+          if ( !error )
+          {
+            *aglyph = glyph;
+            goto Exit;
+          }
+        }
+        else
+          error = FTC_Err_Invalid_Argument;
+      }
+    }
+  Exit:
+    return error;
+  }
+
+
+  static FT_Bool
+  ftc_basic_gnode_compare_faceid( FTC_GNode   gnode,
+                                  FTC_FaceID  face_id,
+                                  FTC_Cache   cache )
+  {
+    FTC_BasicFamily  family = (FTC_BasicFamily) gnode->family;
+    FT_Bool          result;
+
+    result = FT_BOOL( family->attrs.scaler.face_id == face_id );
+    if ( result )
+    {
+     /* we must call this function to avoid this node from appearing
+      * in later lookups with the same face_id !!
+      */
+      FTC_GNode_UnselectFamily( gnode, cache );
+    }
+    return result;
+  }
+
+
+
+ /*
+  *
+  * basic image cache
+  *
+  */
+
+  static const FTC_IFamilyClassRec  ftc_basic_image_family_class =
+  {
+    {
+      sizeof( FTC_BasicFamilyRec ),
+      (FTC_MruNode_CompareFunc)  ftc_basic_family_compare,
+      (FTC_MruNode_InitFunc)     ftc_basic_family_init,
+      (FTC_MruNode_ResetFunc)    NULL,
+      (FTC_MruNode_DoneFunc)     NULL
+    },
+    (FTC_IFamily_LoadGlyphFunc)  ftc_basic_family_load_glyph
+  };
+
+
+
+  static const FTC_GCacheClassRec  ftc_basic_image_cache_class =
+  {
+    {
+      (FTC_Node_NewFunc)      FTC_INode_New,
+      (FTC_Node_WeightFunc)   FTC_INode_Weight,
+      (FTC_Node_CompareFunc)  FTC_GNode_Compare,
+      (FTC_Node_CompareFunc)  ftc_basic_gnode_compare_faceid,
+      (FTC_Node_FreeFunc)     FTC_INode_Free,
+
+      sizeof( FTC_GCacheRec ),
+      (FTC_Cache_InitFunc)    FTC_GCache_Init,
+      (FTC_Cache_DoneFunc)    FTC_GCache_Done
+    },
+    (FTC_MruListClass) & ftc_basic_image_family_class
+  };
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_ImageCache_New( FTC_Manager      manager,
+                      FTC_ImageCache  *acache )
+  {
+    return FTC_GCache_New( manager, & ftc_basic_image_cache_class,
+                           (FTC_GCache*) acache );
+  }
+
+
+  /* documentation is in ftcimage.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_ImageCache_Lookup( FTC_ImageCache  cache,
+                         FTC_ImageType   type,
+                         FT_UInt         gindex,
+                         FT_Glyph       *aglyph,
+                         FTC_Node       *anode )
+  {
+    FTC_BasicQueryRec  query;
+    FTC_INode          node;
+    FT_Error           error;
+    FT_UInt32          hash;
+
+
+    /* some argument checks are delayed to FTC_Cache_Lookup */
+    if ( !aglyph )
+    {
+      error = FTC_Err_Invalid_Argument;
+      goto Exit;
+    }
+
+    *aglyph = NULL;
+    if ( anode )
+      *anode  = NULL;
+
+    query.attrs.scaler.face_id = type->face_id;
+    query.attrs.scaler.width   = type->width;
+    query.attrs.scaler.height  = type->height;
+    query.attrs.scaler.pixel   = 1;
+    query.attrs.load_flags     = type->flags;
+
+    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;
+    
+#if 1  /* inlining is about 50% faster !! */ 
+    FTC_GCACHE_LOOKUP_CMP( cache,
+                           ftc_basic_family_compare,
+                           FTC_GNode_Compare,
+                           hash, gindex,
+                           &query,
+                           node,
+                           error );
+#else
+    error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
+                               hash, gindex,
+                               FTC_GQUERY( &query ),
+                               (FTC_Node*) &node );
+#endif
+    if ( !error )
+    {
+      *aglyph = FTC_INODE(node)->glyph;
+
+      if ( anode )
+      {
+        *anode = FTC_NODE(node);
+        FTC_NODE(node)->ref_count++;
+      }
+    }
+
+  Exit:
+    return error;
+  }
+
+
+
+ /*
+  *
+  * basic small bitmap cache
+  *
+  */
+
+
+  static const FTC_SFamilyClassRec  ftc_basic_sbit_family_class =
+  {
+    {
+      sizeof( FTC_BasicFamilyRec ),
+      (FTC_MruNode_CompareFunc)  ftc_basic_family_compare,
+      (FTC_MruNode_InitFunc)     ftc_basic_family_init,
+      (FTC_MruNode_ResetFunc)    NULL,
+      (FTC_MruNode_DoneFunc)     NULL
+    },
+    (FTC_SFamily_GetCountFunc)   ftc_basic_family_get_count,
+    (FTC_SFamily_LoadGlyphFunc)  ftc_basic_family_load_bitmap
+  };
+
+
+  static const FTC_GCacheClassRec  ftc_basic_sbit_cache_class =
+  {
+    {
+      (FTC_Node_NewFunc)      FTC_SNode_New,
+      (FTC_Node_WeightFunc)   FTC_SNode_Weight,
+      (FTC_Node_CompareFunc)  FTC_SNode_Compare,
+      (FTC_Node_CompareFunc)  ftc_basic_gnode_compare_faceid,
+      (FTC_Node_FreeFunc)     FTC_SNode_Free,
+
+      sizeof( FTC_GCacheRec ),
+      (FTC_Cache_InitFunc)    FTC_GCache_Init,
+      (FTC_Cache_DoneFunc)    FTC_GCache_Done
+    },
+    (FTC_MruListClass) & ftc_basic_sbit_family_class
+  };
+
+
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_SBitCache_New( FTC_Manager     manager,
+                     FTC_SBitCache  *acache )
+  {
+    return FTC_GCache_New( manager, & ftc_basic_sbit_cache_class,
+                           (FTC_GCache*) acache );
+  }
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_SBitCache_Lookup( FTC_SBitCache   cache,
+                        FTC_ImageType   type,
+                        FT_UInt         gindex,
+                        FTC_SBit       *ansbit,
+                        FTC_Node       *anode )
+  {
+    FT_Error           error;
+    FTC_BasicQueryRec  query;
+    FTC_SNode          node;
+    FT_UInt32          hash;
+
+    if ( anode )
+      *anode = NULL;
+
+    /* other argument checks delayed to FTC_Cache_Lookup */
+    if ( !ansbit )
+      return FTC_Err_Invalid_Argument;
+
+    *ansbit = NULL;
+
+    query.attrs.scaler.face_id = type->face_id;
+    query.attrs.scaler.width   = type->width;
+    query.attrs.scaler.height  = type->height;
+    query.attrs.scaler.pixel   = 1;
+    query.attrs.load_flags     = type->flags;
+
+   /* beware, the hash must be the same for all glyph ranges !!
+    */
+    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
+           (gindex/FTC_SBIT_ITEMS_PER_NODE);
+
+#if 1  /* inlining is about 50% faster !! */ 
+    FTC_GCACHE_LOOKUP_CMP( cache,
+                           ftc_basic_family_compare,
+                           FTC_SNode_Compare,
+                           hash, gindex,
+                           &query,
+                           node,
+                           error );
+#else
+    error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
+                               hash,
+                               gindex,
+                               FTC_GQUERY( &query ),
+                               (FTC_Node*) &node );
+#endif                               
+    if ( error )
+      goto Exit;
+
+    *ansbit = node->sbits + ( gindex - FTC_GNODE(node)->gindex );
+
+    if ( anode )
+    {
+      *anode = FTC_NODE( node );
+      FTC_NODE( node )->ref_count++;
+    }
+
+  Exit:
+    return error;
+  }
+
--- a/src/cache/ftccache.c
+++ b/src/cache/ftccache.c
@@ -1,578 +1,578 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftccache.c                                                             */
-/*                                                                         */
-/*    The FreeType internal cache interface (body).                        */
-/*                                                                         */
-/*  Copyright 2000-2001, 2002, 2003 by                                     */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-#include <ft2build.h>
-#include FT_CACHE_INTERNAL_MANAGER_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
-
-#include "ftcerror.h"
-
-
-#define FTC_HASH_MAX_LOAD  2
-#define FTC_HASH_MIN_LOAD  1
-#define FTC_HASH_SUB_LOAD  ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD )
-
-/* this one _must_ be a power of 2! */
-#define FTC_HASH_INITIAL_SIZE  8
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                   CACHE NODE DEFINITIONS                      *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  /* add a new node to the head of the manager's circular MRU list */
-  static void
-  ftc_node_mru_link( FTC_Node     node,
-                     FTC_Manager  manager )
-  {
-    FTC_MruNode_Prepend( (FTC_MruNode*)&manager->nodes_list, (FTC_MruNode)node );
-    manager->num_nodes++;
-  }
-
-
-  /* remove a node from the manager's MRU list */
-  static void
-  ftc_node_mru_unlink( FTC_Node     node,
-                       FTC_Manager  manager )
-  {
-    FTC_MruNode_Remove( (FTC_MruNode*)&manager->nodes_list, (FTC_MruNode)node );
-    manager->num_nodes--;
-  }
-
-
-  /* move a node to the head of the manager's MRU list */
-  static void
-  ftc_node_mru_up( FTC_Node     node,
-                   FTC_Manager  manager )
-  {
-    FTC_MruNode_Up( (FTC_MruNode*)&manager->nodes_list, (FTC_MruNode)node );
-  }
-
-
- /* note that this function cannot fail. If we cannot re-size the
-  * buckets array appropriately, we simply degrade the hash table's
-  * performance !!
-  */
-  static void
-  ftc_cache_resize( FTC_Cache  cache )
-  {
-    for (;;)
-    {
-      FTC_Node   node, *pnode;
-      FT_UInt    p      = cache->p;
-      FT_UInt    mask   = cache->mask;
-      FT_UInt    count  = mask + p + 1;    /* number of buckets */
-
-     /* do we need to shrink the buckets array ?
-      */
-      if ( cache->slack < 0 )
-      {
-        FTC_Node   new_list = NULL;
-
-        /* try to expand the buckets array _before_ splitting
-         * the bucket lists
-         */
-         if ( p >= mask )
-         {
-           FT_Memory  memory = cache->memory;
-
-          /* if we can't expand the array, leave immediately */
-           if ( FT_MEM_RENEW_ARRAY( cache->buckets, (mask+1)*2, (mask+1)*4 ) )
-             break;
-         }
-
-        /* split a single bucket */
-         pnode = cache->buckets + p;
-
-         for (;;)
-         {
-           node = *pnode;
-           if ( node == NULL )
-             break;
-
-           if ( node->hash & ( mask + 1 ) )
-           {
-             *pnode     = node->link;
-             node->link = new_list;
-             new_list   = node;
-           }
-           else
-             pnode = &node->link;
-         }
-
-         cache->buckets[p + mask + 1] = new_list;
-
-         cache->slack += FTC_HASH_MAX_LOAD;
-
-        if ( p >= mask )
-        {
-          cache->mask = 2 * mask + 1;
-          cache->p    = 0;
-        }
-        else
-          cache->p = p + 1;
-      }
-     /* do we need to expand the buckets array ?
-      */
-      else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD )
-      {
-        FT_UInt    old_index = p + mask;
-        FTC_Node*  pold;
-
-        if ( old_index + 1 <= FTC_HASH_INITIAL_SIZE )
-          break;
-
-        if ( p == 0 )
-        {
-          FT_Memory  memory = cache->memory;
-
-         /* if we can't shrink the array, leave immediately */
-          if ( FT_MEM_RENEW_ARRAY( cache->buckets, ( mask + 1 ) * 2, (mask+1) ) )
-            break;
-
-          cache->mask >>= 1;
-          p             = cache->mask;
-        }
-        else
-          p--;
-
-        pnode = cache->buckets + p;
-        while ( *pnode )
-          pnode = &(*pnode)->link;
-
-        pold   = cache->buckets + old_index;
-        *pnode = *pold;
-        *pold  = NULL;
-
-        cache->slack -= FTC_HASH_MAX_LOAD;
-        cache->p      = p;
-      }
-      else /* the hash table is balanced */
-        break;
-    }
-  }
-
-
-
-  /* remove a node from its cache's hash table */
-  static void
-  ftc_node_hash_unlink( FTC_Node   node0,
-                        FTC_Cache  cache )
-  {
-    FTC_Node  *pnode;
-    FT_UInt    idx;
-
-
-    idx = (FT_UInt)( node0->hash & cache->mask );
-    if ( idx < cache->p )
-      idx = (FT_UInt)( node0->hash & ( 2 * cache->mask + 1 ) );
-
-    pnode = cache->buckets + idx;
-
-    for (;;)
-    {
-      FTC_Node  node = *pnode;
-
-      if ( node == NULL )
-      {
-        FT_ERROR(( "ftc_node_hash_unlink: unknown node!\n" ));
-        return;
-      }
-
-      if ( node == node0 )
-        break;
-
-      pnode = &(*pnode)->link;
-    }
-
-    *pnode      = node0->link;
-    node0->link = NULL;
-
-    cache->slack++;
-    ftc_cache_resize( cache );
-  }
-
-
-
-  /* add a node to the "top" of its cache's hash table */
-  static void
-  ftc_node_hash_link( FTC_Node   node,
-                      FTC_Cache  cache )
-  {
-    FTC_Node  *pnode;
-    FT_UInt    idx;
-
-
-    idx = (FT_UInt)( node->hash & cache->mask );
-    if ( idx < cache->p )
-      idx = (FT_UInt)( node->hash & (2 * cache->mask + 1 ) );
-
-    pnode = cache->buckets + idx;
-
-    node->link = *pnode;
-    *pnode     = node;
-
-    cache->slack--;
-    ftc_cache_resize( cache );
-  }
-
-
-
-
-  /* remove a node from the cache manager */
-  FT_EXPORT_DEF( void )
-  ftc_node_destroy( FTC_Node     node,
-                    FTC_Manager  manager )
-  {
-    FTC_Cache  cache;
-
-
-#ifdef FT_DEBUG_ERROR
-    /* find node's cache */
-    if ( node->cache_index >= manager->num_caches )
-    {
-      FT_ERROR(( "ftc_node_destroy: invalid node handle\n" ));
-      return;
-    }
-#endif
-
-    cache = manager->caches[ node->cache_index ];
-
-#ifdef FT_DEBUG_ERROR
-    if ( cache == NULL )
-    {
-      FT_ERROR(( "ftc_node_destroy: invalid node handle\n" ));
-      return;
-    }
-#endif
-
-    manager->cur_weight -= cache->clazz.node_weight( node, cache );
-
-    /* remove node from mru list */
-    ftc_node_mru_unlink( node, manager );
-
-    /* remove node from cache's hash table */
-    ftc_node_hash_unlink( node, cache );
-
-    /* now finalize it */
-    cache->clazz.node_free( node, cache );
-
-#if 0
-    /* check, just in case of general corruption :-) */
-    if ( manager->num_nodes == 0 )
-      FT_ERROR(( "ftc_node_destroy: invalid cache node count! = %d\n",
-                  manager->num_nodes ));
-#endif
-  }
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                    ABSTRACT CACHE CLASS                       *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_Cache_Init( FTC_Cache       cache )
-  {
-    FT_Memory  memory = cache->memory;
-
-    cache->p       = 0;
-    cache->mask    = FTC_HASH_INITIAL_SIZE - 1;
-    cache->slack   = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD;
-
-    return ( FT_MEM_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 ) );
-  }
-
-
-
-  FT_EXPORT_DEF( void )
-  FTC_Cache_Clear( FTC_Cache  cache )
-  {
-    if ( cache )
-    {
-      FTC_Manager  manager = cache->manager;
-      FT_UFast     i;
-      FT_UInt      count;
-
-      count = cache->p + cache->mask + 1;
-
-      for ( i = 0; i < count; i++ )
-      {
-        FTC_Node  *pnode = cache->buckets + i, next, node = *pnode;
-
-
-        while ( node )
-        {
-          next        = node->link;
-          node->link  = NULL;
-
-          /* remove node from mru list */
-          ftc_node_mru_unlink( node, manager );
-
-          /* now finalize it */
-          manager->cur_weight -= cache->clazz.node_weight( node, cache );
-
-          cache->clazz.node_free( node, cache );
-          node = next;
-        }
-        cache->buckets[i] = NULL;
-      }
-      ftc_cache_resize( cache );
-    }
-  }
-
-
-  FT_EXPORT_DEF( void )
-  FTC_Cache_Done( FTC_Cache  cache )
-  {
-    if ( cache->memory )
-    {
-      FT_Memory  memory = cache->memory;
-
-      FTC_Cache_Clear( cache );
-
-      FT_FREE( cache->buckets );
-      cache->mask  = 0;
-      cache->p     = 0;
-      cache->slack = 0;
-
-      cache->memory = NULL;
-    }
-  }
-
-
-
-  static void
-  ftc_cache_add( FTC_Cache    cache,
-                 FT_UInt32    hash,
-                 FTC_Node     node )
-  {
-    node->hash = hash;
-    node->cache_index = (FT_UInt16) cache->index;
-    node->ref_count   = 0;
-
-    ftc_node_hash_link( node, cache );
-    ftc_node_mru_link( node, cache->manager );
-
-    {
-      FTC_Manager  manager = cache->manager;
-
-      manager->cur_weight += cache->clazz.node_weight( node, cache );
-
-      if ( manager->cur_weight >= manager->max_weight )
-      {
-        node->ref_count++;
-        FTC_Manager_Compress( manager );
-        node->ref_count--;
-      }
-    }
-  }
-
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_Cache_NewNode( FTC_Cache   cache,
-                     FT_UInt32   hash,
-                     FT_Pointer  query,
-                     FTC_Node   *anode )
-  {
-    FT_Error  error;
-    FTC_Node  node;
-
-   /*
-    *  try to allocate a new cache node. Note that in case of
-    *  out-of-memory error (OOM), we'll flush the cache a bit,
-    *  then try again.
-    *
-    *  on each try, the "tries" variable gives the number
-    *  of old nodes we want to flush from the manager's global list
-    *  before the next allocation attempt. it barely doubles on
-    *  each iteration
-    *
-    */
-    error = cache->clazz.node_new( &node, query, cache );
-    if ( error )
-      goto FlushCache;
-
-  AddNode:
-   /* don't assume that the cache has the same number of buckets, since
-    * our allocation request might have triggered global cache flushing
-    */
-    ftc_cache_add( cache, hash, node );
-
-  Exit:
-    *anode = node;
-    return error;
-
-  FlushCache:
-    node = NULL;
-    if ( error != FT_Err_Out_Of_Memory )
-      goto Exit;
-
-    {
-      FTC_Manager  manager = cache->manager;
-      FT_UInt      count, tries = 1;
-
-      for (;;)
-      {
-        error = cache->clazz.node_new( &node, query, cache );
-        if ( !error )
-          break;
-
-        node = NULL;
-        if ( error != FT_Err_Out_Of_Memory )
-          goto Exit;
-
-        count = FTC_Manager_FlushN( manager, tries );
-        if ( count == 0 )
-          goto Exit;
-
-        if ( count == tries )
-        {
-          count = tries*2;
-          if ( count < tries || count > manager->num_nodes )
-            count = manager->num_nodes;
-        }
-        tries = count;
-      }
-    }
-    goto AddNode;
-  }                     
-
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_Cache_Lookup( FTC_Cache   cache,
-                    FT_UInt32   hash,
-                    FT_Pointer  query,
-                    FTC_Node   *anode )
-  {
-    FT_UFast   idx;
-    FTC_Node*  bucket;
-    FTC_Node*  pnode;
-    FTC_Node   node;
-    FT_Error   error = 0;
-
-    FTC_Node_CompareFunc  compare = cache->clazz.node_compare;
-
-
-    if ( cache == NULL || anode == NULL )
-      return FT_Err_Invalid_Argument;
-
-    idx = hash & cache->mask;
-    if ( idx < cache->p )
-      idx = hash & ( cache->mask * 2 + 1 );
-
-    bucket = cache->buckets + idx;
-    pnode  = bucket;
-    for (;;)
-    {
-      node = *pnode;
-      if ( node == NULL )
-        goto NewNode;
-
-      if ( node->hash == hash && compare( node, query, cache ) )
-        break;
-
-      pnode = &node->link;
-    }
-
-    if ( node != *bucket )
-    {
-      *pnode     = node->link;
-      node->link = *bucket;
-      *bucket    = node;
-    }
-
-    /* move to head of MRU list */
-    {
-      FTC_Manager  manager = cache->manager;
-
-      if ( node != manager->nodes_list )
-        ftc_node_mru_up( node, manager );
-    }
-    *anode = node;
-    return error;
-
-  NewNode:
-    return FTC_Cache_NewNode( cache, hash, query, anode );
-  }
-
-
-
-
-  FT_EXPORT_DEF( void )
-  FTC_Cache_RemoveFaceID( FTC_Cache    cache,
-                           FTC_FaceID   face_id )
-  {
-    FT_UFast     i, count;
-    FTC_Manager  manager = cache->manager;
-    FTC_Node     free    = NULL;
-
-    count = cache->p + cache->mask;
-    for ( i = 0; i < count; i++ )
-    {
-      FTC_Node*  bucket = cache->buckets + i;
-      FTC_Node*  pnode  = bucket;
-
-      for ( ;; )
-      {
-        FTC_Node  node = *pnode;
-
-        if ( node == NULL )
-          break;
-
-        if ( cache->clazz.node_remove_faceid( node, face_id, cache ) )
-        {
-          *pnode = node->link;
-          node->link = free;
-          free       = node;
-        }
-        else
-          pnode = &node->link;
-      }
-    }
-
-   /* remove all nodes in the free list
-    */
-    while ( free )
-    {
-      FTC_Node  node;
-
-      node = free;
-      free = node->link;
-
-      manager->cur_weight -= cache->clazz.node_weight( node, cache );
-      ftc_node_mru_unlink( node, manager );
-
-      cache->clazz.node_free( node, cache );
-
-      cache->slack ++;
-    }
-
-    ftc_cache_resize( cache );
-  }
-
-/* END */
+/***************************************************************************/
+/*                                                                         */
+/*  ftccache.c                                                             */
+/*                                                                         */
+/*    The FreeType internal cache interface (body).                        */
+/*                                                                         */
+/*  Copyright 2000-2001, 2002, 2003 by                                     */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_CACHE_INTERNAL_MANAGER_H
+#include FT_INTERNAL_OBJECTS_H
+#include FT_INTERNAL_DEBUG_H
+
+#include "ftcerror.h"
+
+
+#define FTC_HASH_MAX_LOAD  2
+#define FTC_HASH_MIN_LOAD  1
+#define FTC_HASH_SUB_LOAD  ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD )
+
+/* this one _must_ be a power of 2! */
+#define FTC_HASH_INITIAL_SIZE  8
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                   CACHE NODE DEFINITIONS                      *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /* add a new node to the head of the manager's circular MRU list */
+  static void
+  ftc_node_mru_link( FTC_Node     node,
+                     FTC_Manager  manager )
+  {
+    FTC_MruNode_Prepend( (FTC_MruNode*)&manager->nodes_list, (FTC_MruNode)node );
+    manager->num_nodes++;
+  }
+
+
+  /* remove a node from the manager's MRU list */
+  static void
+  ftc_node_mru_unlink( FTC_Node     node,
+                       FTC_Manager  manager )
+  {
+    FTC_MruNode_Remove( (FTC_MruNode*)&manager->nodes_list, (FTC_MruNode)node );
+    manager->num_nodes--;
+  }
+
+
+  /* move a node to the head of the manager's MRU list */
+  static void
+  ftc_node_mru_up( FTC_Node     node,
+                   FTC_Manager  manager )
+  {
+    FTC_MruNode_Up( (FTC_MruNode*)&manager->nodes_list, (FTC_MruNode)node );
+  }
+
+
+ /* note that this function cannot fail. If we cannot re-size the
+  * buckets array appropriately, we simply degrade the hash table's
+  * performance !!
+  */
+  static void
+  ftc_cache_resize( FTC_Cache  cache )
+  {
+    for (;;)
+    {
+      FTC_Node   node, *pnode;
+      FT_UInt    p      = cache->p;
+      FT_UInt    mask   = cache->mask;
+      FT_UInt    count  = mask + p + 1;    /* number of buckets */
+
+     /* do we need to shrink the buckets array ?
+      */
+      if ( cache->slack < 0 )
+      {
+        FTC_Node   new_list = NULL;
+
+        /* try to expand the buckets array _before_ splitting
+         * the bucket lists
+         */
+         if ( p >= mask )
+         {
+           FT_Memory  memory = cache->memory;
+
+          /* if we can't expand the array, leave immediately */
+           if ( FT_MEM_RENEW_ARRAY( cache->buckets, (mask+1)*2, (mask+1)*4 ) )
+             break;
+         }
+
+        /* split a single bucket */
+         pnode = cache->buckets + p;
+
+         for (;;)
+         {
+           node = *pnode;
+           if ( node == NULL )
+             break;
+
+           if ( node->hash & ( mask + 1 ) )
+           {
+             *pnode     = node->link;
+             node->link = new_list;
+             new_list   = node;
+           }
+           else
+             pnode = &node->link;
+         }
+
+         cache->buckets[p + mask + 1] = new_list;
+
+         cache->slack += FTC_HASH_MAX_LOAD;
+
+        if ( p >= mask )
+        {
+          cache->mask = 2 * mask + 1;
+          cache->p    = 0;
+        }
+        else
+          cache->p = p + 1;
+      }
+     /* do we need to expand the buckets array ?
+      */
+      else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD )
+      {
+        FT_UInt    old_index = p + mask;
+        FTC_Node*  pold;
+
+        if ( old_index + 1 <= FTC_HASH_INITIAL_SIZE )
+          break;
+
+        if ( p == 0 )
+        {
+          FT_Memory  memory = cache->memory;
+
+         /* if we can't shrink the array, leave immediately */
+          if ( FT_MEM_RENEW_ARRAY( cache->buckets, ( mask + 1 ) * 2, (mask+1) ) )
+            break;
+
+          cache->mask >>= 1;
+          p             = cache->mask;
+        }
+        else
+          p--;
+
+        pnode = cache->buckets + p;
+        while ( *pnode )
+          pnode = &(*pnode)->link;
+
+        pold   = cache->buckets + old_index;
+        *pnode = *pold;
+        *pold  = NULL;
+
+        cache->slack -= FTC_HASH_MAX_LOAD;
+        cache->p      = p;
+      }
+      else /* the hash table is balanced */
+        break;
+    }
+  }
+
+
+
+  /* remove a node from its cache's hash table */
+  static void
+  ftc_node_hash_unlink( FTC_Node   node0,
+                        FTC_Cache  cache )
+  {
+    FTC_Node  *pnode;
+    FT_UInt    idx;
+
+
+    idx = (FT_UInt)( node0->hash & cache->mask );
+    if ( idx < cache->p )
+      idx = (FT_UInt)( node0->hash & ( 2 * cache->mask + 1 ) );
+
+    pnode = cache->buckets + idx;
+
+    for (;;)
+    {
+      FTC_Node  node = *pnode;
+
+      if ( node == NULL )
+      {
+        FT_ERROR(( "ftc_node_hash_unlink: unknown node!\n" ));
+        return;
+      }
+
+      if ( node == node0 )
+        break;
+
+      pnode = &(*pnode)->link;
+    }
+
+    *pnode      = node0->link;
+    node0->link = NULL;
+
+    cache->slack++;
+    ftc_cache_resize( cache );
+  }
+
+
+
+  /* add a node to the "top" of its cache's hash table */
+  static void
+  ftc_node_hash_link( FTC_Node   node,
+                      FTC_Cache  cache )
+  {
+    FTC_Node  *pnode;
+    FT_UInt    idx;
+
+
+    idx = (FT_UInt)( node->hash & cache->mask );
+    if ( idx < cache->p )
+      idx = (FT_UInt)( node->hash & (2 * cache->mask + 1 ) );
+
+    pnode = cache->buckets + idx;
+
+    node->link = *pnode;
+    *pnode     = node;
+
+    cache->slack--;
+    ftc_cache_resize( cache );
+  }
+
+
+
+
+  /* remove a node from the cache manager */
+  FT_EXPORT_DEF( void )
+  ftc_node_destroy( FTC_Node     node,
+                    FTC_Manager  manager )
+  {
+    FTC_Cache  cache;
+
+
+#ifdef FT_DEBUG_ERROR
+    /* find node's cache */
+    if ( node->cache_index >= manager->num_caches )
+    {
+      FT_ERROR(( "ftc_node_destroy: invalid node handle\n" ));
+      return;
+    }
+#endif
+
+    cache = manager->caches[ node->cache_index ];
+
+#ifdef FT_DEBUG_ERROR
+    if ( cache == NULL )
+    {
+      FT_ERROR(( "ftc_node_destroy: invalid node handle\n" ));
+      return;
+    }
+#endif
+
+    manager->cur_weight -= cache->clazz.node_weight( node, cache );
+
+    /* remove node from mru list */
+    ftc_node_mru_unlink( node, manager );
+
+    /* remove node from cache's hash table */
+    ftc_node_hash_unlink( node, cache );
+
+    /* now finalize it */
+    cache->clazz.node_free( node, cache );
+
+#if 0
+    /* check, just in case of general corruption :-) */
+    if ( manager->num_nodes == 0 )
+      FT_ERROR(( "ftc_node_destroy: invalid cache node count! = %d\n",
+                  manager->num_nodes ));
+#endif
+  }
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                    ABSTRACT CACHE CLASS                       *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_Cache_Init( FTC_Cache       cache )
+  {
+    FT_Memory  memory = cache->memory;
+
+    cache->p       = 0;
+    cache->mask    = FTC_HASH_INITIAL_SIZE - 1;
+    cache->slack   = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD;
+
+    return ( FT_MEM_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 ) );
+  }
+
+
+
+  FT_EXPORT_DEF( void )
+  FTC_Cache_Clear( FTC_Cache  cache )
+  {
+    if ( cache )
+    {
+      FTC_Manager  manager = cache->manager;
+      FT_UFast     i;
+      FT_UInt      count;
+
+      count = cache->p + cache->mask + 1;
+
+      for ( i = 0; i < count; i++ )
+      {
+        FTC_Node  *pnode = cache->buckets + i, next, node = *pnode;
+
+
+        while ( node )
+        {
+          next        = node->link;
+          node->link  = NULL;
+
+          /* remove node from mru list */
+          ftc_node_mru_unlink( node, manager );
+
+          /* now finalize it */
+          manager->cur_weight -= cache->clazz.node_weight( node, cache );
+
+          cache->clazz.node_free( node, cache );
+          node = next;
+        }
+        cache->buckets[i] = NULL;
+      }
+      ftc_cache_resize( cache );
+    }
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FTC_Cache_Done( FTC_Cache  cache )
+  {
+    if ( cache->memory )
+    {
+      FT_Memory  memory = cache->memory;
+
+      FTC_Cache_Clear( cache );
+
+      FT_FREE( cache->buckets );
+      cache->mask  = 0;
+      cache->p     = 0;
+      cache->slack = 0;
+
+      cache->memory = NULL;
+    }
+  }
+
+
+
+  static void
+  ftc_cache_add( FTC_Cache    cache,
+                 FT_UInt32    hash,
+                 FTC_Node     node )
+  {
+    node->hash = hash;
+    node->cache_index = (FT_UInt16) cache->index;
+    node->ref_count   = 0;
+
+    ftc_node_hash_link( node, cache );
+    ftc_node_mru_link( node, cache->manager );
+
+    {
+      FTC_Manager  manager = cache->manager;
+
+      manager->cur_weight += cache->clazz.node_weight( node, cache );
+
+      if ( manager->cur_weight >= manager->max_weight )
+      {
+        node->ref_count++;
+        FTC_Manager_Compress( manager );
+        node->ref_count--;
+      }
+    }
+  }
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_Cache_NewNode( FTC_Cache   cache,
+                     FT_UInt32   hash,
+                     FT_Pointer  query,
+                     FTC_Node   *anode )
+  {
+    FT_Error  error;
+    FTC_Node  node;
+
+   /*
+    *  try to allocate a new cache node. Note that in case of
+    *  out-of-memory error (OOM), we'll flush the cache a bit,
+    *  then try again.
+    *
+    *  on each try, the "tries" variable gives the number
+    *  of old nodes we want to flush from the manager's global list
+    *  before the next allocation attempt. it barely doubles on
+    *  each iteration
+    *
+    */
+    error = cache->clazz.node_new( &node, query, cache );
+    if ( error )
+      goto FlushCache;
+
+  AddNode:
+   /* don't assume that the cache has the same number of buckets, since
+    * our allocation request might have triggered global cache flushing
+    */
+    ftc_cache_add( cache, hash, node );
+
+  Exit:
+    *anode = node;
+    return error;
+
+  FlushCache:
+    node = NULL;
+    if ( error != FT_Err_Out_Of_Memory )
+      goto Exit;
+
+    {
+      FTC_Manager  manager = cache->manager;
+      FT_UInt      count, tries = 1;
+
+      for (;;)
+      {
+        error = cache->clazz.node_new( &node, query, cache );
+        if ( !error )
+          break;
+
+        node = NULL;
+        if ( error != FT_Err_Out_Of_Memory )
+          goto Exit;
+
+        count = FTC_Manager_FlushN( manager, tries );
+        if ( count == 0 )
+          goto Exit;
+
+        if ( count == tries )
+        {
+          count = tries*2;
+          if ( count < tries || count > manager->num_nodes )
+            count = manager->num_nodes;
+        }
+        tries = count;
+      }
+    }
+    goto AddNode;
+  }                     
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_Cache_Lookup( FTC_Cache   cache,
+                    FT_UInt32   hash,
+                    FT_Pointer  query,
+                    FTC_Node   *anode )
+  {
+    FT_UFast   idx;
+    FTC_Node*  bucket;
+    FTC_Node*  pnode;
+    FTC_Node   node;
+    FT_Error   error = 0;
+
+    FTC_Node_CompareFunc  compare = cache->clazz.node_compare;
+
+
+    if ( cache == NULL || anode == NULL )
+      return FT_Err_Invalid_Argument;
+
+    idx = hash & cache->mask;
+    if ( idx < cache->p )
+      idx = hash & ( cache->mask * 2 + 1 );
+
+    bucket = cache->buckets + idx;
+    pnode  = bucket;
+    for (;;)
+    {
+      node = *pnode;
+      if ( node == NULL )
+        goto NewNode;
+
+      if ( node->hash == hash && compare( node, query, cache ) )
+        break;
+
+      pnode = &node->link;
+    }
+
+    if ( node != *bucket )
+    {
+      *pnode     = node->link;
+      node->link = *bucket;
+      *bucket    = node;
+    }
+
+    /* move to head of MRU list */
+    {
+      FTC_Manager  manager = cache->manager;
+
+      if ( node != manager->nodes_list )
+        ftc_node_mru_up( node, manager );
+    }
+    *anode = node;
+    return error;
+
+  NewNode:
+    return FTC_Cache_NewNode( cache, hash, query, anode );
+  }
+
+
+
+
+  FT_EXPORT_DEF( void )
+  FTC_Cache_RemoveFaceID( FTC_Cache    cache,
+                           FTC_FaceID   face_id )
+  {
+    FT_UFast     i, count;
+    FTC_Manager  manager = cache->manager;
+    FTC_Node     free    = NULL;
+
+    count = cache->p + cache->mask;
+    for ( i = 0; i < count; i++ )
+    {
+      FTC_Node*  bucket = cache->buckets + i;
+      FTC_Node*  pnode  = bucket;
+
+      for ( ;; )
+      {
+        FTC_Node  node = *pnode;
+
+        if ( node == NULL )
+          break;
+
+        if ( cache->clazz.node_remove_faceid( node, face_id, cache ) )
+        {
+          *pnode = node->link;
+          node->link = free;
+          free       = node;
+        }
+        else
+          pnode = &node->link;
+      }
+    }
+
+   /* remove all nodes in the free list
+    */
+    while ( free )
+    {
+      FTC_Node  node;
+
+      node = free;
+      free = node->link;
+
+      manager->cur_weight -= cache->clazz.node_weight( node, cache );
+      ftc_node_mru_unlink( node, manager );
+
+      cache->clazz.node_free( node, cache );
+
+      cache->slack ++;
+    }
+
+    ftc_cache_resize( cache );
+  }
+
+/* END */
--- a/src/cache/ftccmap.c
+++ b/src/cache/ftccmap.c
@@ -1,271 +1,271 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftccmap.c                                                              */
-/*                                                                         */
-/*    FreeType CharMap cache (body)                                        */
-/*                                                                         */
-/*  Copyright 2000-2001, 2002, 2003 by                                     */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_CACHE_H
-#include FT_CACHE_INTERNAL_MANAGER_H
-#include FT_INTERNAL_MEMORY_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_TRUETYPE_IDS_H
-
-#include "ftcerror.h"
-
-#undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cache
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Each FTC_CMapNode contains a simple array to map a range of character */
-  /* codes to equivalent glyph indices.                                    */
-  /*                                                                       */
-  /* For now, the implementation is very basic: Each node maps a range of  */
-  /* 128 consecutive character codes to their corresponding glyph indices. */
-  /*                                                                       */
-  /* We could do more complex things, but I don't think it is really very  */
-  /* useful.                                                               */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /* number of glyph indices / character code per node */
-#define FTC_CMAP_INDICES_MAX  128
-
-  /* compute a query/node hash */
-#define  FTC_CMAP_HASH( faceid, index, charcode )    \
-   ( FTC_FACE_ID_HASH( faceid ) + 211*( index ) + ((char_code) / FTC_CMAP_INDICES_MAX) )
-
-  /* the charmap query */
-  typedef struct  FTC_CMapQueryRec_
-  {
-    FTC_FaceID    face_id;
-    FT_UInt       cmap_index;
-    FT_UInt32     char_code;
-
-  } FTC_CMapQueryRec, *FTC_CMapQuery;
-
-#define  FTC_CMAP_QUERY(x)  ((FTC_CMapQuery)(x))
-#define  FTC_CMAP_QUERY_HASH(x)  FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code )
-
- /* the cmap cache node */
-  typedef struct  FTC_CMapNodeRec_
-  {
-    FTC_NodeRec  node;
-    FTC_FaceID   face_id;
-    FT_UInt      cmap_index;
-    FT_UInt32    first;                         /* first character in node */
-    FT_UInt16    indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices  */
-
-  } FTC_CMapNodeRec, *FTC_CMapNode;
-
-#define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) )
-#define FTC_CMAP_NODE_HASH(x)  FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first )
-
-  /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */
-  /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet   */
-#define FTC_CMAP_UNKNOWN  ( (FT_UInt16)-1 )
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                        CHARMAP NODES                          *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /* no need for specific finalizer; we use "ftc_node_done" directly */
-
-  FT_CALLBACK_DEF( void )
-  ftc_cmap_node_free( FTC_CMapNode   node,
-                      FTC_Cache      cache )
-  {
-    FT_Memory  memory = cache->memory;
-
-    FT_FREE( node );
-  }
-
-
-  /* initialize a new cmap node */
-  FT_CALLBACK_DEF( FT_Error )
-  ftc_cmap_node_new( FTC_CMapNode  *anode,
-                     FTC_CMapQuery  query,
-                     FTC_Cache      cache )
-  {
-    FT_Error      error;
-    FT_Memory     memory  = cache->memory;
-    FTC_CMapNode  node;
-    FT_UInt       nn;
-
-    if ( !FT_NEW( node ) )
-    {
-      node->face_id    = query->face_id;
-      node->cmap_index = query->cmap_index;
-      node->first      = (query->char_code / FTC_CMAP_INDICES_MAX) *
-                         FTC_CMAP_INDICES_MAX;
-
-      for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ )
-        node->indices[nn] = FTC_CMAP_UNKNOWN;
-    }
-
-    *anode = node;
-    return error;
-  }
-
-
-  /* compute the weight of a given cmap node */
-  FT_CALLBACK_DEF( FT_ULong )
-  ftc_cmap_node_weight( FTC_CMapNode  cnode )
-  {
-    FT_UNUSED( cnode );
-
-    return sizeof ( *cnode );
-  }
-
-
-  /* compare a cmap node to a given query */
-  FT_CALLBACK_DEF( FT_Bool )
-  ftc_cmap_node_compare( FTC_CMapNode   node,
-                         FTC_CMapQuery  query )
-  {
-    if ( node->face_id    == query->face_id    &&
-         node->cmap_index == query->cmap_index )
-    {
-      FT_UInt32  offset = (FT_UInt32)( query->char_code - node->first );
-
-      return FT_BOOL( offset < FTC_CMAP_INDICES_MAX );
-    }
-    return 0;
-  }
-
-
-  FT_CALLBACK_DEF( FT_Bool )
-  ftc_cmap_node_remove_faceid( FTC_CMapNode  node,
-                               FTC_FaceID    face_id )
-  {
-    return FT_BOOL( node->face_id == face_id );
-  }
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                    GLYPH IMAGE CACHE                          *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  FT_CALLBACK_TABLE_DEF
-  const FTC_CacheClassRec  ftc_cmap_cache_class =
-  {
-    (FTC_Node_NewFunc)      ftc_cmap_node_new,
-    (FTC_Node_WeightFunc)   ftc_cmap_node_weight,
-    (FTC_Node_CompareFunc)  ftc_cmap_node_compare,
-    (FTC_Node_CompareFunc)  ftc_cmap_node_remove_faceid,
-    (FTC_Node_FreeFunc)     ftc_cmap_node_free,
-
-    sizeof ( FTC_CacheRec ),
-    (FTC_Cache_InitFunc) FTC_Cache_Init,
-    (FTC_Cache_DoneFunc) FTC_Cache_Done,
-  };
-
-  /* documentation is in ftccmap.h */
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_CMapCache_New( FTC_Manager     manager,
-                     FTC_CMapCache  *acache )
-  {
-    return FTC_Manager_RegisterCache( manager,
-                                      & ftc_cmap_cache_class,
-                                      FTC_CACHE_P( acache ) );
-  }
-  /* documentation is in ftccmap.h */
-
-  FT_EXPORT_DEF( FT_UInt )
-  FTC_CMapCache_Lookup( FTC_CMapCache  cmap_cache,
-                        FTC_FaceID     face_id,
-                        FT_Int         cmap_index,
-                        FT_UInt32      char_code )
-  {
-    FTC_Cache         cache = FTC_CACHE( cmap_cache );
-    FTC_CMapQueryRec  query;
-    FTC_CMapNode      node;
-    FT_Error          error;
-    FT_UInt           gindex = 0;
-    FT_UInt32         hash;
-
-
-    if ( !cache )
-    {
-      FT_ERROR(( "FTC_CMapCache_Lookup: bad arguments, returning 0!\n" ));
-      return 0;
-    }
-
-    query.face_id    = face_id;
-    query.cmap_index = (FT_UInt)cmap_index;
-    query.char_code  = char_code;
-
-    hash = FTC_CMAP_HASH( face_id, cmap_index, char_code );
-
-#if 1
-    FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query,
-                          node, error );
-#else
-    error = FTC_Cache_Lookup( cache, hash, &query, (FTC_Node*) &node );
-#endif    
-    if ( error )
-      goto Exit;
-
-    FT_ASSERT( (FT_UInt)( char_code - node->first ) < FTC_CMAP_INDICES_MAX );
-
-    gindex = node->indices[ char_code - node->first ];
-    if ( gindex == FTC_CMAP_UNKNOWN )
-    {
-      FT_Face     face;
-
-      gindex = 0;
-
-      error = FTC_Manager_LookupFace( cache->manager, node->face_id, &face );
-      if ( error )
-        goto Exit;
-
-      if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps )
-      {
-        FT_CharMap  old, cmap  = NULL;
-
-        old  = face->charmap;
-        cmap = face->charmaps[ cmap_index ];
-
-        if (old != cmap)
-          FT_Set_Charmap( face, cmap );
-
-        gindex = FT_Get_Char_Index( face, char_code );
-
-        if (old != cmap)
-          FT_Set_Charmap( face, old );
-      }
-
-      node->indices[ char_code - node->first ] = gindex;
-    }
-
-  Exit:
-    return gindex;
-  }
-
-/* END */
+/***************************************************************************/
+/*                                                                         */
+/*  ftccmap.c                                                              */
+/*                                                                         */
+/*    FreeType CharMap cache (body)                                        */
+/*                                                                         */
+/*  Copyright 2000-2001, 2002, 2003 by                                     */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_CACHE_H
+#include FT_CACHE_INTERNAL_MANAGER_H
+#include FT_INTERNAL_MEMORY_H
+#include FT_INTERNAL_DEBUG_H
+#include FT_TRUETYPE_IDS_H
+
+#include "ftcerror.h"
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_cache
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Each FTC_CMapNode contains a simple array to map a range of character */
+  /* codes to equivalent glyph indices.                                    */
+  /*                                                                       */
+  /* For now, the implementation is very basic: Each node maps a range of  */
+  /* 128 consecutive character codes to their corresponding glyph indices. */
+  /*                                                                       */
+  /* We could do more complex things, but I don't think it is really very  */
+  /* useful.                                                               */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /* number of glyph indices / character code per node */
+#define FTC_CMAP_INDICES_MAX  128
+
+  /* compute a query/node hash */
+#define  FTC_CMAP_HASH( faceid, index, charcode )    \
+   ( FTC_FACE_ID_HASH( faceid ) + 211*( index ) + ((char_code) / FTC_CMAP_INDICES_MAX) )
+
+  /* the charmap query */
+  typedef struct  FTC_CMapQueryRec_
+  {
+    FTC_FaceID    face_id;
+    FT_UInt       cmap_index;
+    FT_UInt32     char_code;
+
+  } FTC_CMapQueryRec, *FTC_CMapQuery;
+
+#define  FTC_CMAP_QUERY(x)  ((FTC_CMapQuery)(x))
+#define  FTC_CMAP_QUERY_HASH(x)  FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code )
+
+ /* the cmap cache node */
+  typedef struct  FTC_CMapNodeRec_
+  {
+    FTC_NodeRec  node;
+    FTC_FaceID   face_id;
+    FT_UInt      cmap_index;
+    FT_UInt32    first;                         /* first character in node */
+    FT_UInt16    indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices  */
+
+  } FTC_CMapNodeRec, *FTC_CMapNode;
+
+#define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) )
+#define FTC_CMAP_NODE_HASH(x)  FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first )
+
+  /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */
+  /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet   */
+#define FTC_CMAP_UNKNOWN  ( (FT_UInt16)-1 )
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                        CHARMAP NODES                          *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /* no need for specific finalizer; we use "ftc_node_done" directly */
+
+  FT_CALLBACK_DEF( void )
+  ftc_cmap_node_free( FTC_CMapNode   node,
+                      FTC_Cache      cache )
+  {
+    FT_Memory  memory = cache->memory;
+
+    FT_FREE( node );
+  }
+
+
+  /* initialize a new cmap node */
+  FT_CALLBACK_DEF( FT_Error )
+  ftc_cmap_node_new( FTC_CMapNode  *anode,
+                     FTC_CMapQuery  query,
+                     FTC_Cache      cache )
+  {
+    FT_Error      error;
+    FT_Memory     memory  = cache->memory;
+    FTC_CMapNode  node;
+    FT_UInt       nn;
+
+    if ( !FT_NEW( node ) )
+    {
+      node->face_id    = query->face_id;
+      node->cmap_index = query->cmap_index;
+      node->first      = (query->char_code / FTC_CMAP_INDICES_MAX) *
+                         FTC_CMAP_INDICES_MAX;
+
+      for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ )
+        node->indices[nn] = FTC_CMAP_UNKNOWN;
+    }
+
+    *anode = node;
+    return error;
+  }
+
+
+  /* compute the weight of a given cmap node */
+  FT_CALLBACK_DEF( FT_ULong )
+  ftc_cmap_node_weight( FTC_CMapNode  cnode )
+  {
+    FT_UNUSED( cnode );
+
+    return sizeof ( *cnode );
+  }
+
+
+  /* compare a cmap node to a given query */
+  FT_CALLBACK_DEF( FT_Bool )
+  ftc_cmap_node_compare( FTC_CMapNode   node,
+                         FTC_CMapQuery  query )
+  {
+    if ( node->face_id    == query->face_id    &&
+         node->cmap_index == query->cmap_index )
+    {
+      FT_UInt32  offset = (FT_UInt32)( query->char_code - node->first );
+
+      return FT_BOOL( offset < FTC_CMAP_INDICES_MAX );
+    }
+    return 0;
+  }
+
+
+  FT_CALLBACK_DEF( FT_Bool )
+  ftc_cmap_node_remove_faceid( FTC_CMapNode  node,
+                               FTC_FaceID    face_id )
+  {
+    return FT_BOOL( node->face_id == face_id );
+  }
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                    GLYPH IMAGE CACHE                          *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  FT_CALLBACK_TABLE_DEF
+  const FTC_CacheClassRec  ftc_cmap_cache_class =
+  {
+    (FTC_Node_NewFunc)      ftc_cmap_node_new,
+    (FTC_Node_WeightFunc)   ftc_cmap_node_weight,
+    (FTC_Node_CompareFunc)  ftc_cmap_node_compare,
+    (FTC_Node_CompareFunc)  ftc_cmap_node_remove_faceid,
+    (FTC_Node_FreeFunc)     ftc_cmap_node_free,
+
+    sizeof ( FTC_CacheRec ),
+    (FTC_Cache_InitFunc) FTC_Cache_Init,
+    (FTC_Cache_DoneFunc) FTC_Cache_Done,
+  };
+
+  /* documentation is in ftccmap.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_CMapCache_New( FTC_Manager     manager,
+                     FTC_CMapCache  *acache )
+  {
+    return FTC_Manager_RegisterCache( manager,
+                                      & ftc_cmap_cache_class,
+                                      FTC_CACHE_P( acache ) );
+  }
+  /* documentation is in ftccmap.h */
+
+  FT_EXPORT_DEF( FT_UInt )
+  FTC_CMapCache_Lookup( FTC_CMapCache  cmap_cache,
+                        FTC_FaceID     face_id,
+                        FT_Int         cmap_index,
+                        FT_UInt32      char_code )
+  {
+    FTC_Cache         cache = FTC_CACHE( cmap_cache );
+    FTC_CMapQueryRec  query;
+    FTC_CMapNode      node;
+    FT_Error          error;
+    FT_UInt           gindex = 0;
+    FT_UInt32         hash;
+
+
+    if ( !cache )
+    {
+      FT_ERROR(( "FTC_CMapCache_Lookup: bad arguments, returning 0!\n" ));
+      return 0;
+    }
+
+    query.face_id    = face_id;
+    query.cmap_index = (FT_UInt)cmap_index;
+    query.char_code  = char_code;
+
+    hash = FTC_CMAP_HASH( face_id, cmap_index, char_code );
+
+#if 1
+    FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query,
+                          node, error );
+#else
+    error = FTC_Cache_Lookup( cache, hash, &query, (FTC_Node*) &node );
+#endif    
+    if ( error )
+      goto Exit;
+
+    FT_ASSERT( (FT_UInt)( char_code - node->first ) < FTC_CMAP_INDICES_MAX );
+
+    gindex = node->indices[ char_code - node->first ];
+    if ( gindex == FTC_CMAP_UNKNOWN )
+    {
+      FT_Face     face;
+
+      gindex = 0;
+
+      error = FTC_Manager_LookupFace( cache->manager, node->face_id, &face );
+      if ( error )
+        goto Exit;
+
+      if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps )
+      {
+        FT_CharMap  old, cmap  = NULL;
+
+        old  = face->charmap;
+        cmap = face->charmaps[ cmap_index ];
+
+        if (old != cmap)
+          FT_Set_Charmap( face, cmap );
+
+        gindex = FT_Get_Char_Index( face, char_code );
+
+        if (old != cmap)
+          FT_Set_Charmap( face, old );
+      }
+
+      node->indices[ char_code - node->first ] = gindex;
+    }
+
+  Exit:
+    return gindex;
+  }
+
+/* END */
--- a/src/cache/ftcglyph.c
+++ b/src/cache/ftcglyph.c
@@ -1,152 +1,152 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftcglyph.c                                                             */
-/*                                                                         */
-/*    FreeType Glyph Image (FT_Glyph) cache (body).                        */
-/*                                                                         */
-/*  Copyright 2000-2001 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-#include <ft2build.h>
-#include FT_CACHE_H
-#include FT_CACHE_INTERNAL_GLYPH_H
-#include FT_ERRORS_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
-
-#include "ftcerror.h"
-
-
-  /* create a new chunk node, setting its cache index and ref count */
-  FT_EXPORT_DEF( void )
-  FTC_GNode_Init( FTC_GNode   gnode,
-                  FT_UInt     gindex,
-                  FTC_Family  family )
-  {
-    gnode->family = family;
-    gnode->gindex = gindex;
-    family->num_nodes++;
-  }
-
-
-  FT_EXPORT_DEF( void )
-  FTC_GNode_UnselectFamily( FTC_GNode   gnode,
-                            FTC_Cache   cache )
-  {
-    FTC_Family  family = gnode->family;
-
-    gnode->family = NULL;
-    if ( family && --family->num_nodes <= 0 )
-    {
-      FTC_MruList_Remove( & FTC_GCACHE(cache)->families, (FTC_MruNode)family );
-  }
-  }
-
-
-  FT_EXPORT_DEF( void )
-  FTC_GNode_Done( FTC_GNode  gnode,
-                  FTC_Cache  cache )
-  {
-    /* finalize the node */
-    gnode->gindex = 0;
-
-    FTC_GNode_UnselectFamily( gnode, cache );
-  }
-
-
-  FT_EXPORT_DEF( FT_Bool )
-  FTC_GNode_Compare( FTC_GNode   gnode,
-                     FTC_GQuery  gquery )
-  {
-    return FT_BOOL(  gnode->family == gquery->family &&
-                     gnode->gindex == gquery->gindex );
-  }
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                      CHUNK SETS                               *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  FT_EXPORT_DEF( void )
-  FTC_Family_Init( FTC_Family  family,
-                   FTC_Cache   cache )
-  {
-    FTC_GCacheClass  clazz = FTC_CACHE__GCACHE_CLASS(cache);
-
-    family->clazz     = clazz->family_class;
-    family->num_nodes = 0;
-    family->cache     = cache;
-  }
-
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_GCache_Init( FTC_GCache  cache )
-  {
-    FT_Error error;
-
-    error = FTC_Cache_Init( FTC_CACHE(cache) );
-    if ( !error )
-    {
-      FTC_GCacheClass   clazz = (FTC_GCacheClass) FTC_CACHE(cache)->org_class;
-
-      FTC_MruList_Init( &cache->families,
-                        clazz->family_class,
-                        0,  /* no maximum here !! */
-                        cache,
-                        FTC_CACHE(cache)->memory );
-    }
-    return error;
-  }
-
-
-  FT_EXPORT_DEF( void )
-  FTC_GCache_Done( FTC_GCache  cache )
-  {
-    FTC_Cache_Done( (FTC_Cache)cache );
-    FTC_MruList_Done( &cache->families );
-  }
-
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_GCache_New( FTC_Manager       manager,
-                  FTC_GCacheClass   clazz,
-                  FTC_GCache       *acache )
-  {
-    return FTC_Manager_RegisterCache( manager, (FTC_CacheClass) clazz,
-                                      (FTC_Cache*) acache );
-  }
-
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_GCache_Lookup( FTC_GCache   cache,
-                     FT_UInt32    hash,
-                     FT_UInt      gindex,
-                     FTC_GQuery   query,
-                     FTC_Node    *anode )
-  {
-    FT_Error    error;
-
-    query->gindex = gindex;
-
-    FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error );
-    if ( !error )
-      error = FTC_Cache_Lookup( FTC_CACHE(cache), hash, query, anode );
-
-    return error;
-  }
-
-
-/* END */
+/***************************************************************************/
+/*                                                                         */
+/*  ftcglyph.c                                                             */
+/*                                                                         */
+/*    FreeType Glyph Image (FT_Glyph) cache (body).                        */
+/*                                                                         */
+/*  Copyright 2000-2001 by                                                 */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_CACHE_H
+#include FT_CACHE_INTERNAL_GLYPH_H
+#include FT_ERRORS_H
+#include FT_INTERNAL_OBJECTS_H
+#include FT_INTERNAL_DEBUG_H
+
+#include "ftcerror.h"
+
+
+  /* create a new chunk node, setting its cache index and ref count */
+  FT_EXPORT_DEF( void )
+  FTC_GNode_Init( FTC_GNode   gnode,
+                  FT_UInt     gindex,
+                  FTC_Family  family )
+  {
+    gnode->family = family;
+    gnode->gindex = gindex;
+    family->num_nodes++;
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FTC_GNode_UnselectFamily( FTC_GNode   gnode,
+                            FTC_Cache   cache )
+  {
+    FTC_Family  family = gnode->family;
+
+    gnode->family = NULL;
+    if ( family && --family->num_nodes <= 0 )
+    {
+      FTC_MruList_Remove( & FTC_GCACHE(cache)->families, (FTC_MruNode)family );
+  }
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FTC_GNode_Done( FTC_GNode  gnode,
+                  FTC_Cache  cache )
+  {
+    /* finalize the node */
+    gnode->gindex = 0;
+
+    FTC_GNode_UnselectFamily( gnode, cache );
+  }
+
+
+  FT_EXPORT_DEF( FT_Bool )
+  FTC_GNode_Compare( FTC_GNode   gnode,
+                     FTC_GQuery  gquery )
+  {
+    return FT_BOOL(  gnode->family == gquery->family &&
+                     gnode->gindex == gquery->gindex );
+  }
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                      CHUNK SETS                               *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  FT_EXPORT_DEF( void )
+  FTC_Family_Init( FTC_Family  family,
+                   FTC_Cache   cache )
+  {
+    FTC_GCacheClass  clazz = FTC_CACHE__GCACHE_CLASS(cache);
+
+    family->clazz     = clazz->family_class;
+    family->num_nodes = 0;
+    family->cache     = cache;
+  }
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_GCache_Init( FTC_GCache  cache )
+  {
+    FT_Error error;
+
+    error = FTC_Cache_Init( FTC_CACHE(cache) );
+    if ( !error )
+    {
+      FTC_GCacheClass   clazz = (FTC_GCacheClass) FTC_CACHE(cache)->org_class;
+
+      FTC_MruList_Init( &cache->families,
+                        clazz->family_class,
+                        0,  /* no maximum here !! */
+                        cache,
+                        FTC_CACHE(cache)->memory );
+    }
+    return error;
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FTC_GCache_Done( FTC_GCache  cache )
+  {
+    FTC_Cache_Done( (FTC_Cache)cache );
+    FTC_MruList_Done( &cache->families );
+  }
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_GCache_New( FTC_Manager       manager,
+                  FTC_GCacheClass   clazz,
+                  FTC_GCache       *acache )
+  {
+    return FTC_Manager_RegisterCache( manager, (FTC_CacheClass) clazz,
+                                      (FTC_Cache*) acache );
+  }
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_GCache_Lookup( FTC_GCache   cache,
+                     FT_UInt32    hash,
+                     FT_UInt      gindex,
+                     FTC_GQuery   query,
+                     FTC_Node    *anode )
+  {
+    FT_Error    error;
+
+    query->gindex = gindex;
+
+    FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error );
+    if ( !error )
+      error = FTC_Cache_Lookup( FTC_CACHE(cache), hash, query, anode );
+
+    return error;
+  }
+
+
+/* END */
--- a/src/cache/ftcmanag.c
+++ b/src/cache/ftcmanag.c
@@ -1,645 +1,645 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftcmanag.c                                                             */
-/*                                                                         */
-/*    FreeType Cache Manager (body).                                       */
-/*                                                                         */
-/*  Copyright 2000-2001, 2002 by                                           */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-#include <ft2build.h>
-#include FT_CACHE_H
-#include FT_CACHE_INTERNAL_MANAGER_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_SIZES_H
-
-#include "ftcerror.h"
-
-
-#undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cache
-
-#define FTC_LRU_GET_MANAGER( lru )  ( (FTC_Manager)(lru)->user_data )
-
-
-  static FT_Error
-  ftc_scaler_lookup_size( FTC_Manager    manager,
-                          FTC_Scaler     scaler,
-                          FT_Size       *asize )
-  {
-    FT_Face   face;
-    FT_Size   size = NULL;
-    FT_Error  error;
-
-    error = FTC_Manager_LookupFace( manager, scaler->face_id, &face );
-    if ( error ) goto Exit;
-
-    error = FT_New_Size( face, &size );
-    if ( error ) goto Exit;
-
-    FT_Activate_Size( size );
-
-    if ( scaler->pixel )
-      error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height );
-    else
-      error = FT_Set_Char_Size( face, scaler->width, scaler->height,
-                                scaler->x_res, scaler->y_res );
-    if ( error )
-    {
-      FT_Done_Size( size );
-      size = NULL;
-    }
-
-  Exit:
-    *asize = size;
-    return error;
-  }
-
-
-  typedef struct FTC_SizeNodeRec_
-  {
-    FTC_MruNodeRec    node;
-    FT_Size           size;
-    FTC_ScalerRec     scaler;
-
-  } FTC_SizeNodeRec, *FTC_SizeNode;
-
-
-  FT_CALLBACK_DEF( void )
-  ftc_size_node_done( FTC_SizeNode  node )
-  {
-    FT_Size  size = node->size;
-
-    if ( size )
-      FT_Done_Size( size );
-  }
-
-
-  FT_CALLBACK_DEF( FT_Bool )
-  ftc_size_node_compare( FTC_SizeNode  node,
-                         FTC_Scaler    scaler )
-  {
-    FTC_Scaler  scaler0 = &node->scaler;
-
-    return FTC_SCALER_COMPARE( scaler0, scaler );
-  }
-
-
-
-  FT_CALLBACK_DEF( FT_Error )
-  ftc_size_node_init( FTC_SizeNode   node,
-                      FTC_Scaler     scaler,
-                      FTC_Manager    manager )
-  {
-    node->scaler = scaler[0];
-
-    return ftc_scaler_lookup_size( manager, scaler, &node->size );
-  }
-
-
-  FT_CALLBACK_DEF( FT_Error )
-  ftc_size_node_reset( FTC_SizeNode       node,
-                       FTC_Scaler         scaler,
-                       FTC_Manager        manager )
-  {
-    FT_Done_Size( node->size );
-
-    node->scaler = scaler[0];
-
-    return ftc_scaler_lookup_size( manager, scaler, &node->size );
-  }
-
-
-  static const FTC_MruListClassRec  ftc_size_list_class =
-  {
-    sizeof( FTC_SizeNodeRec ),
-    (FTC_MruNode_CompareFunc)  ftc_size_node_compare,
-    (FTC_MruNode_InitFunc)     ftc_size_node_init,
-    (FTC_MruNode_ResetFunc)    ftc_size_node_reset,
-    (FTC_MruNode_DoneFunc)     ftc_size_node_done
-  };
-
-
- /* helper function used by ftc_face_node_done */
-  static FT_Bool
-  ftc_size_node_compare_faceid( FTC_SizeNode  node,
-                                FTC_FaceID    face_id )
-  {
-    return FT_BOOL( node->scaler.face_id == face_id );
-  }
-
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_Manager_LookupSize( FTC_Manager    manager,
-                          FTC_Scaler     scaler,
-                          FT_Size       *asize )
-  {
-    FT_Error      error;
-    FTC_SizeNode  node;
-
-
-    if ( asize == NULL )
-      return FTC_Err_Bad_Argument;
-
-    *asize = NULL;
-
-    if ( !manager )
-      return FTC_Err_Invalid_Cache_Handle;
-
-    /* we break encapsulation for the sake of speed */
-    
-    error = 0;
-    FTC_MRULIST_LOOP( &manager->sizes, node )
-    {
-      FTC_Scaler  scaler0 = &node->scaler;
-      
-      if ( FTC_SCALER_COMPARE( scaler0, scaler ) )
-        goto Found;
-    }
-    FTC_MRULIST_LOOP_END();
-    
-    error = FTC_MruList_New( &manager->sizes, scaler, (FTC_MruNode*)&node );
-    
-  Found:
-    if ( !error )
-      *asize = node->size;
-
-    return error;
-  }
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                    FACE MRU IMPLEMENTATION                    *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  typedef struct  FTC_FaceNodeRec_
-  {
-    FTC_MruNodeRec  node;
-    FTC_FaceID      face_id;
-    FT_Face         face;
-
-  } FTC_FaceNodeRec, *FTC_FaceNode;
-
-
-
-  FT_CALLBACK_DEF( FT_Error )
-  ftc_face_node_init( FTC_FaceNode  node,
-                      FTC_FaceID    face_id,
-                      FTC_Manager   manager )
-  {
-    FT_Error      error;
-
-    node->face_id = face_id;
-
-    error = manager->request_face( face_id,
-                                   manager->library,
-                                   manager->request_data,
-                                   &node->face );
-    if ( !error )
-    {
-      /* destroy initial size object; it will be re-created later */
-      if ( node->face->size )
-        FT_Done_Size( node->face->size );
-    }
-    return error;
-  }
-
-
-  FT_CALLBACK_DEF( void )
-  ftc_face_node_done( FTC_FaceNode  node,
-                      FTC_Manager   manager )
-  {
-    /* we must begin by removing all scalers for the target face */
-    /* from the manager's list                                   */
-    FTC_MruList_RemoveSelection(
-          & manager->sizes,
-          (FTC_MruNode_CompareFunc) ftc_size_node_compare_faceid,
-          node->face_id );
-
-    /* all right, we can discard the face now */
-    FT_Done_Face( node->face );
-    node->face    = NULL;
-    node->face_id = NULL;
-  }
-
-
-  FT_CALLBACK_DEF( FT_Bool )
-  ftc_face_node_compare( FTC_FaceNode  node,
-                         FTC_FaceID    face_id )
-  {
-    return FT_BOOL( node->face_id == face_id );
-  }
-
-
-  static const FTC_MruListClassRec  ftc_face_list_class =
-  {
-    sizeof( FTC_FaceNodeRec),
-
-    (FTC_MruNode_CompareFunc) ftc_face_node_compare,
-    (FTC_MruNode_InitFunc)    ftc_face_node_init,
-    (FTC_MruNode_ResetFunc)   NULL,
-    (FTC_MruNode_DoneFunc)    ftc_face_node_done
-  };
-
-
-
-  /* documentation is in ftcache.h */
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_Manager_LookupFace( FTC_Manager  manager,
-                          FTC_FaceID   face_id,
-                          FT_Face     *aface )
-  {
-    FT_Error      error;
-    FTC_FaceNode  node;
-
-
-    if ( aface == NULL )
-      return FTC_Err_Bad_Argument;
-
-    *aface = NULL;
-
-    if ( !manager )
-      return FTC_Err_Invalid_Cache_Handle;
-
-    /* we break encapsulation for the sake of speed */
-
-    error = 0;
-    FTC_MRULIST_LOOP( &manager->faces, node )
-    {
-      if ( node->face_id == face_id )
-        goto Found;
-    }
-    FTC_MRULIST_LOOP_END();
-    
-    error = FTC_MruList_New( &manager->faces, face_id, (FTC_MruNode*)&node );
-    
-  Found:
-    if ( !error )
-      *aface = node->face;
-
-    return error;
-  }
-
-
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                    CACHE MANAGER ROUTINES                     *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /* documentation is in ftcache.h */
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_Manager_New( FT_Library          library,
-                   FT_UInt             max_faces,
-                   FT_UInt             max_sizes,
-                   FT_ULong            max_bytes,
-                   FTC_Face_Requester  requester,
-                   FT_Pointer          req_data,
-                   FTC_Manager        *amanager )
-  {
-    FT_Error     error;
-    FT_Memory    memory;
-    FTC_Manager  manager = 0;
-
-
-    if ( !library )
-      return FTC_Err_Invalid_Library_Handle;
-
-    memory = library->memory;
-
-    if ( FT_NEW( manager ) )
-      goto Exit;
-
-    if ( max_faces == 0 )
-      max_faces = FTC_MAX_FACES_DEFAULT;
-
-    if ( max_sizes == 0 )
-      max_sizes = FTC_MAX_SIZES_DEFAULT;
-
-    if ( max_bytes == 0 )
-      max_bytes = FTC_MAX_BYTES_DEFAULT;
-
-    manager->library      = library;
-    manager->memory       = memory;
-    manager->max_weight   = max_bytes;
-
-    manager->request_face = requester;
-    manager->request_data = req_data;
-
-    FTC_MruList_Init( &manager->faces,
-                      &ftc_face_list_class,
-                      max_faces,
-                      manager,
-                      memory );
-
-    FTC_MruList_Init( &manager->sizes,
-                      &ftc_size_list_class,
-                      max_sizes,
-                      manager,
-                      memory );
-
-    *amanager = manager;
-
-  Exit:
-    return error;
-  }
-
-
-  /* documentation is in ftcache.h */
-
-  FT_EXPORT_DEF( void )
-  FTC_Manager_Done( FTC_Manager  manager )
-  {
-    FT_Memory  memory;
-    FT_UInt    idx;
-
-
-    if ( !manager || !manager->library )
-      return;
-
-    memory = manager->memory;
-
-    /* now discard all caches */
-    for (idx = manager->num_caches; idx-- > 0; )
-    {
-      FTC_Cache  cache = manager->caches[idx];
-
-      if ( cache )
-      {
-        cache->clazz.cache_done( cache );
-        FT_FREE( cache );
-        manager->caches[idx] = NULL;
-      }
-    }
-    manager->num_caches = 0;
-
-    /* discard faces and sizes */
-    FTC_MruList_Done( &manager->sizes );
-    FTC_MruList_Done( &manager->faces );
-
-    manager->library = NULL;
-    manager->memory  = NULL;
-
-    FT_FREE( manager );
-  }
-
-
-  /* documentation is in ftcache.h */
-
-  FT_EXPORT_DEF( void )
-  FTC_Manager_Reset( FTC_Manager  manager )
-  {
-    if ( manager )
-    {
-      FTC_MruList_Reset( &manager->sizes );
-      FTC_MruList_Reset( &manager->faces );
-    }
-    /* XXX: FIXME: flush the caches? */
-  }
-
-
-#ifdef FT_DEBUG_ERROR
-
-  FT_EXPORT_DEF( void )
-  FTC_Manager_Check( FTC_Manager  manager )
-  {
-    FTC_Node  node, first;
-
-
-    first = manager->nodes_list;
-
-    /* check node weights */
-    if ( first )
-    {
-      FT_ULong  weight = 0;
-
-
-      node = first;
-
-      do
-      {
-        FTC_Cache     cache = manager->caches[ node->cache_index ];
-
-        if ( (FT_UInt)node->cache_index >= manager->num_caches )
-          FT_ERROR(( "FTC_Manager_Check: invalid node (cache index = %ld\n",
-                     node->cache_index ));
-        else
-        {
-          weight += cache->clazz.node_weight( node, cache );
-        }
-
-        node = FTC_NODE__NEXT(node);
-
-      } while ( node != first );
-
-      if ( weight != manager->cur_weight )
-        FT_ERROR(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n",
-                   manager->cur_weight, weight ));
-    }
-
-    /* check circular list */
-    if ( first )
-    {
-      FT_UFast  count = 0;
-
-
-      node = first;
-      do
-      {
-        count++;
-        node = FTC_NODE__NEXT(node);
-
-      } while ( node != first );
-
-      if ( count != manager->num_nodes )
-        FT_ERROR((
-          "FTC_Manager_Check: invalid cache node count %d instead of %d\n",
-          manager->num_nodes, count ));
-    }
-  }
-
-#endif /* FT_DEBUG_ERROR */
-
-
-  /* `Compress' the manager's data, i.e., get rid of old cache nodes */
-  /* that are not referenced anymore in order to limit the total     */
-  /* memory used by the cache.                                       */
-
-  /* documentation is in ftcmanag.h */
-
-  FT_EXPORT_DEF( void )
-  FTC_Manager_Compress( FTC_Manager  manager )
-  {
-    FTC_Node   node, first;
-
-
-    if ( !manager )
-      return;
-
-    first = manager->nodes_list;
-
-#ifdef FT_DEBUG_ERROR
-    FTC_Manager_Check( manager );
-
-    FT_ERROR(( "compressing, weight = %ld, max = %ld, nodes = %d\n",
-               manager->cur_weight, manager->max_weight,
-               manager->num_nodes ));
-#endif
-
-    if ( manager->cur_weight < manager->max_weight || first == NULL )
-      return;
-
-    /* go to last node - it's a circular list */
-    node = FTC_NODE__PREV(first);
-    do
-    {
-      FTC_Node  prev;
-
-
-      prev = ( node == first ) ? NULL : FTC_NODE__PREV(node);
-
-      if ( node->ref_count <= 0 )
-        ftc_node_destroy( node, manager );
-
-      node = prev;
-
-    } while ( node && manager->cur_weight > manager->max_weight );
-  }
-
-
-  /* documentation is in ftcmanag.h */
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_Manager_RegisterCache( FTC_Manager      manager,
-                              FTC_CacheClass   clazz,
-                              FTC_Cache       *acache )
-  {
-    FT_Error   error = FTC_Err_Invalid_Argument;
-    FTC_Cache  cache = NULL;
-
-
-    if ( manager && clazz && acache )
-    {
-      FT_Memory  memory = manager->memory;
-
-      if ( manager->num_caches >= FTC_MAX_CACHES )
-      {
-        error = FTC_Err_Too_Many_Caches;
-        FT_ERROR(( "%s: too many registered caches\n",
-                   "FTC_Manager_Register_Cache" ));
-        goto Exit;
-      }
-
-      if ( !FT_ALLOC( cache, clazz->cache_size ) )
-      {
-        cache->manager   = manager;
-        cache->memory    = memory;
-        cache->clazz     = clazz[0];
-        cache->org_class = clazz;
-
-        /* THIS IS VERY IMPORTANT!  IT WILL WRETCH THE MANAGER */
-        /* IF IT IS NOT SET CORRECTLY                          */
-        cache->index = manager->num_caches;
-
-        error = clazz->cache_init( cache );
-        if ( error )
-        {
-          clazz->cache_done( cache );
-          FT_FREE( cache );
-          goto Exit;
-        }
-
-        manager->caches[ manager->num_caches++ ] = cache;
-      }
-    }
-
-  Exit:
-    *acache = cache;
-    return error;
-  }
-
-
-  FT_EXPORT_DEF( FT_UInt )
-  FTC_Manager_FlushN( FTC_Manager  manager,
-                       FT_UInt      count )
-  {
-    FTC_Node  first = manager->nodes_list;
-    FTC_Node  node;
-    FT_UInt   result;
-
-    /* try to remove "count" nodes from the list */
-    if ( first == NULL )  /* empty list! */
-      return 0;
-
-    /* go to last node - it's a circular list */
-    node = FTC_NODE__PREV(first);
-    for ( result = 0; result < count; )
-    {
-      FTC_Node  prev = FTC_NODE__PREV(node);
-
-
-     /* don't touch locked nodes */
-      if ( node->ref_count <= 0 )
-      {
-        ftc_node_destroy( node, manager );
-        result++;
-      }
-
-      if ( prev == manager->nodes_list )
-        break;
-
-      node = prev;
-    }
-    return  result;
-  }
-
-
-  FT_EXPORT_DEF( void )
-  FTC_Manager_RemoveFaceID( FTC_Manager  manager,
-                            FTC_FaceID   face_id )
-  {
-    FT_UInt  nn;
-
-   /* this will remove all FTC_SizeNode that correspond to
-    * the face_id as well
-    */
-    FTC_MruList_RemoveSelection( &manager->faces, NULL, face_id );
-
-    for ( nn = 0; nn < manager->num_caches; nn++ )
-      FTC_Cache_RemoveFaceID( manager->caches[nn], face_id );
-  }
-
-
-  /* documentation is in ftcmanag.h */
-
-  FT_EXPORT_DEF( void )
-  FTC_Node_Unref( FTC_Node     node,
-                  FTC_Manager  manager )
-  {
-    if ( node && (FT_UInt)node->cache_index < manager->num_caches )
-      node->ref_count--;
-  }
-
-
-/* END */
+/***************************************************************************/
+/*                                                                         */
+/*  ftcmanag.c                                                             */
+/*                                                                         */
+/*    FreeType Cache Manager (body).                                       */
+/*                                                                         */
+/*  Copyright 2000-2001, 2002 by                                           */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_CACHE_H
+#include FT_CACHE_INTERNAL_MANAGER_H
+#include FT_INTERNAL_OBJECTS_H
+#include FT_INTERNAL_DEBUG_H
+#include FT_SIZES_H
+
+#include "ftcerror.h"
+
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_cache
+
+#define FTC_LRU_GET_MANAGER( lru )  ( (FTC_Manager)(lru)->user_data )
+
+
+  static FT_Error
+  ftc_scaler_lookup_size( FTC_Manager    manager,
+                          FTC_Scaler     scaler,
+                          FT_Size       *asize )
+  {
+    FT_Face   face;
+    FT_Size   size = NULL;
+    FT_Error  error;
+
+    error = FTC_Manager_LookupFace( manager, scaler->face_id, &face );
+    if ( error ) goto Exit;
+
+    error = FT_New_Size( face, &size );
+    if ( error ) goto Exit;
+
+    FT_Activate_Size( size );
+
+    if ( scaler->pixel )
+      error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height );
+    else
+      error = FT_Set_Char_Size( face, scaler->width, scaler->height,
+                                scaler->x_res, scaler->y_res );
+    if ( error )
+    {
+      FT_Done_Size( size );
+      size = NULL;
+    }
+
+  Exit:
+    *asize = size;
+    return error;
+  }
+
+
+  typedef struct FTC_SizeNodeRec_
+  {
+    FTC_MruNodeRec    node;
+    FT_Size           size;
+    FTC_ScalerRec     scaler;
+
+  } FTC_SizeNodeRec, *FTC_SizeNode;
+
+
+  FT_CALLBACK_DEF( void )
+  ftc_size_node_done( FTC_SizeNode  node )
+  {
+    FT_Size  size = node->size;
+
+    if ( size )
+      FT_Done_Size( size );
+  }
+
+
+  FT_CALLBACK_DEF( FT_Bool )
+  ftc_size_node_compare( FTC_SizeNode  node,
+                         FTC_Scaler    scaler )
+  {
+    FTC_Scaler  scaler0 = &node->scaler;
+
+    return FTC_SCALER_COMPARE( scaler0, scaler );
+  }
+
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  ftc_size_node_init( FTC_SizeNode   node,
+                      FTC_Scaler     scaler,
+                      FTC_Manager    manager )
+  {
+    node->scaler = scaler[0];
+
+    return ftc_scaler_lookup_size( manager, scaler, &node->size );
+  }
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  ftc_size_node_reset( FTC_SizeNode       node,
+                       FTC_Scaler         scaler,
+                       FTC_Manager        manager )
+  {
+    FT_Done_Size( node->size );
+
+    node->scaler = scaler[0];
+
+    return ftc_scaler_lookup_size( manager, scaler, &node->size );
+  }
+
+
+  static const FTC_MruListClassRec  ftc_size_list_class =
+  {
+    sizeof( FTC_SizeNodeRec ),
+    (FTC_MruNode_CompareFunc)  ftc_size_node_compare,
+    (FTC_MruNode_InitFunc)     ftc_size_node_init,
+    (FTC_MruNode_ResetFunc)    ftc_size_node_reset,
+    (FTC_MruNode_DoneFunc)     ftc_size_node_done
+  };
+
+
+ /* helper function used by ftc_face_node_done */
+  static FT_Bool
+  ftc_size_node_compare_faceid( FTC_SizeNode  node,
+                                FTC_FaceID    face_id )
+  {
+    return FT_BOOL( node->scaler.face_id == face_id );
+  }
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_Manager_LookupSize( FTC_Manager    manager,
+                          FTC_Scaler     scaler,
+                          FT_Size       *asize )
+  {
+    FT_Error      error;
+    FTC_SizeNode  node;
+
+
+    if ( asize == NULL )
+      return FTC_Err_Bad_Argument;
+
+    *asize = NULL;
+
+    if ( !manager )
+      return FTC_Err_Invalid_Cache_Handle;
+
+    /* we break encapsulation for the sake of speed */
+    
+    error = 0;
+    FTC_MRULIST_LOOP( &manager->sizes, node )
+    {
+      FTC_Scaler  scaler0 = &node->scaler;
+      
+      if ( FTC_SCALER_COMPARE( scaler0, scaler ) )
+        goto Found;
+    }
+    FTC_MRULIST_LOOP_END();
+    
+    error = FTC_MruList_New( &manager->sizes, scaler, (FTC_MruNode*)&node );
+    
+  Found:
+    if ( !error )
+      *asize = node->size;
+
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                    FACE MRU IMPLEMENTATION                    *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  typedef struct  FTC_FaceNodeRec_
+  {
+    FTC_MruNodeRec  node;
+    FTC_FaceID      face_id;
+    FT_Face         face;
+
+  } FTC_FaceNodeRec, *FTC_FaceNode;
+
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  ftc_face_node_init( FTC_FaceNode  node,
+                      FTC_FaceID    face_id,
+                      FTC_Manager   manager )
+  {
+    FT_Error      error;
+
+    node->face_id = face_id;
+
+    error = manager->request_face( face_id,
+                                   manager->library,
+                                   manager->request_data,
+                                   &node->face );
+    if ( !error )
+    {
+      /* destroy initial size object; it will be re-created later */
+      if ( node->face->size )
+        FT_Done_Size( node->face->size );
+    }
+    return error;
+  }
+
+
+  FT_CALLBACK_DEF( void )
+  ftc_face_node_done( FTC_FaceNode  node,
+                      FTC_Manager   manager )
+  {
+    /* we must begin by removing all scalers for the target face */
+    /* from the manager's list                                   */
+    FTC_MruList_RemoveSelection(
+          & manager->sizes,
+          (FTC_MruNode_CompareFunc) ftc_size_node_compare_faceid,
+          node->face_id );
+
+    /* all right, we can discard the face now */
+    FT_Done_Face( node->face );
+    node->face    = NULL;
+    node->face_id = NULL;
+  }
+
+
+  FT_CALLBACK_DEF( FT_Bool )
+  ftc_face_node_compare( FTC_FaceNode  node,
+                         FTC_FaceID    face_id )
+  {
+    return FT_BOOL( node->face_id == face_id );
+  }
+
+
+  static const FTC_MruListClassRec  ftc_face_list_class =
+  {
+    sizeof( FTC_FaceNodeRec),
+
+    (FTC_MruNode_CompareFunc) ftc_face_node_compare,
+    (FTC_MruNode_InitFunc)    ftc_face_node_init,
+    (FTC_MruNode_ResetFunc)   NULL,
+    (FTC_MruNode_DoneFunc)    ftc_face_node_done
+  };
+
+
+
+  /* documentation is in ftcache.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_Manager_LookupFace( FTC_Manager  manager,
+                          FTC_FaceID   face_id,
+                          FT_Face     *aface )
+  {
+    FT_Error      error;
+    FTC_FaceNode  node;
+
+
+    if ( aface == NULL )
+      return FTC_Err_Bad_Argument;
+
+    *aface = NULL;
+
+    if ( !manager )
+      return FTC_Err_Invalid_Cache_Handle;
+
+    /* we break encapsulation for the sake of speed */
+
+    error = 0;
+    FTC_MRULIST_LOOP( &manager->faces, node )
+    {
+      if ( node->face_id == face_id )
+        goto Found;
+    }
+    FTC_MRULIST_LOOP_END();
+    
+    error = FTC_MruList_New( &manager->faces, face_id, (FTC_MruNode*)&node );
+    
+  Found:
+    if ( !error )
+      *aface = node->face;
+
+    return error;
+  }
+
+
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                    CACHE MANAGER ROUTINES                     *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /* documentation is in ftcache.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_Manager_New( FT_Library          library,
+                   FT_UInt             max_faces,
+                   FT_UInt             max_sizes,
+                   FT_ULong            max_bytes,
+                   FTC_Face_Requester  requester,
+                   FT_Pointer          req_data,
+                   FTC_Manager        *amanager )
+  {
+    FT_Error     error;
+    FT_Memory    memory;
+    FTC_Manager  manager = 0;
+
+
+    if ( !library )
+      return FTC_Err_Invalid_Library_Handle;
+
+    memory = library->memory;
+
+    if ( FT_NEW( manager ) )
+      goto Exit;
+
+    if ( max_faces == 0 )
+      max_faces = FTC_MAX_FACES_DEFAULT;
+
+    if ( max_sizes == 0 )
+      max_sizes = FTC_MAX_SIZES_DEFAULT;
+
+    if ( max_bytes == 0 )
+      max_bytes = FTC_MAX_BYTES_DEFAULT;
+
+    manager->library      = library;
+    manager->memory       = memory;
+    manager->max_weight   = max_bytes;
+
+    manager->request_face = requester;
+    manager->request_data = req_data;
+
+    FTC_MruList_Init( &manager->faces,
+                      &ftc_face_list_class,
+                      max_faces,
+                      manager,
+                      memory );
+
+    FTC_MruList_Init( &manager->sizes,
+                      &ftc_size_list_class,
+                      max_sizes,
+                      manager,
+                      memory );
+
+    *amanager = manager;
+
+  Exit:
+    return error;
+  }
+
+
+  /* documentation is in ftcache.h */
+
+  FT_EXPORT_DEF( void )
+  FTC_Manager_Done( FTC_Manager  manager )
+  {
+    FT_Memory  memory;
+    FT_UInt    idx;
+
+
+    if ( !manager || !manager->library )
+      return;
+
+    memory = manager->memory;
+
+    /* now discard all caches */
+    for (idx = manager->num_caches; idx-- > 0; )
+    {
+      FTC_Cache  cache = manager->caches[idx];
+
+      if ( cache )
+      {
+        cache->clazz.cache_done( cache );
+        FT_FREE( cache );
+        manager->caches[idx] = NULL;
+      }
+    }
+    manager->num_caches = 0;
+
+    /* discard faces and sizes */
+    FTC_MruList_Done( &manager->sizes );
+    FTC_MruList_Done( &manager->faces );
+
+    manager->library = NULL;
+    manager->memory  = NULL;
+
+    FT_FREE( manager );
+  }
+
+
+  /* documentation is in ftcache.h */
+
+  FT_EXPORT_DEF( void )
+  FTC_Manager_Reset( FTC_Manager  manager )
+  {
+    if ( manager )
+    {
+      FTC_MruList_Reset( &manager->sizes );
+      FTC_MruList_Reset( &manager->faces );
+    }
+    /* XXX: FIXME: flush the caches? */
+  }
+
+
+#ifdef FT_DEBUG_ERROR
+
+  FT_EXPORT_DEF( void )
+  FTC_Manager_Check( FTC_Manager  manager )
+  {
+    FTC_Node  node, first;
+
+
+    first = manager->nodes_list;
+
+    /* check node weights */
+    if ( first )
+    {
+      FT_ULong  weight = 0;
+
+
+      node = first;
+
+      do
+      {
+        FTC_Cache     cache = manager->caches[ node->cache_index ];
+
+        if ( (FT_UInt)node->cache_index >= manager->num_caches )
+          FT_ERROR(( "FTC_Manager_Check: invalid node (cache index = %ld\n",
+                     node->cache_index ));
+        else
+        {
+          weight += cache->clazz.node_weight( node, cache );
+        }
+
+        node = FTC_NODE__NEXT(node);
+
+      } while ( node != first );
+
+      if ( weight != manager->cur_weight )
+        FT_ERROR(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n",
+                   manager->cur_weight, weight ));
+    }
+
+    /* check circular list */
+    if ( first )
+    {
+      FT_UFast  count = 0;
+
+
+      node = first;
+      do
+      {
+        count++;
+        node = FTC_NODE__NEXT(node);
+
+      } while ( node != first );
+
+      if ( count != manager->num_nodes )
+        FT_ERROR((
+          "FTC_Manager_Check: invalid cache node count %d instead of %d\n",
+          manager->num_nodes, count ));
+    }
+  }
+
+#endif /* FT_DEBUG_ERROR */
+
+
+  /* `Compress' the manager's data, i.e., get rid of old cache nodes */
+  /* that are not referenced anymore in order to limit the total     */
+  /* memory used by the cache.                                       */
+
+  /* documentation is in ftcmanag.h */
+
+  FT_EXPORT_DEF( void )
+  FTC_Manager_Compress( FTC_Manager  manager )
+  {
+    FTC_Node   node, first;
+
+
+    if ( !manager )
+      return;
+
+    first = manager->nodes_list;
+
+#ifdef FT_DEBUG_ERROR
+    FTC_Manager_Check( manager );
+
+    FT_ERROR(( "compressing, weight = %ld, max = %ld, nodes = %d\n",
+               manager->cur_weight, manager->max_weight,
+               manager->num_nodes ));
+#endif
+
+    if ( manager->cur_weight < manager->max_weight || first == NULL )
+      return;
+
+    /* go to last node - it's a circular list */
+    node = FTC_NODE__PREV(first);
+    do
+    {
+      FTC_Node  prev;
+
+
+      prev = ( node == first ) ? NULL : FTC_NODE__PREV(node);
+
+      if ( node->ref_count <= 0 )
+        ftc_node_destroy( node, manager );
+
+      node = prev;
+
+    } while ( node && manager->cur_weight > manager->max_weight );
+  }
+
+
+  /* documentation is in ftcmanag.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_Manager_RegisterCache( FTC_Manager      manager,
+                              FTC_CacheClass   clazz,
+                              FTC_Cache       *acache )
+  {
+    FT_Error   error = FTC_Err_Invalid_Argument;
+    FTC_Cache  cache = NULL;
+
+
+    if ( manager && clazz && acache )
+    {
+      FT_Memory  memory = manager->memory;
+
+      if ( manager->num_caches >= FTC_MAX_CACHES )
+      {
+        error = FTC_Err_Too_Many_Caches;
+        FT_ERROR(( "%s: too many registered caches\n",
+                   "FTC_Manager_Register_Cache" ));
+        goto Exit;
+      }
+
+      if ( !FT_ALLOC( cache, clazz->cache_size ) )
+      {
+        cache->manager   = manager;
+        cache->memory    = memory;
+        cache->clazz     = clazz[0];
+        cache->org_class = clazz;
+
+        /* THIS IS VERY IMPORTANT!  IT WILL WRETCH THE MANAGER */
+        /* IF IT IS NOT SET CORRECTLY                          */
+        cache->index = manager->num_caches;
+
+        error = clazz->cache_init( cache );
+        if ( error )
+        {
+          clazz->cache_done( cache );
+          FT_FREE( cache );
+          goto Exit;
+        }
+
+        manager->caches[ manager->num_caches++ ] = cache;
+      }
+    }
+
+  Exit:
+    *acache = cache;
+    return error;
+  }
+
+
+  FT_EXPORT_DEF( FT_UInt )
+  FTC_Manager_FlushN( FTC_Manager  manager,
+                       FT_UInt      count )
+  {
+    FTC_Node  first = manager->nodes_list;
+    FTC_Node  node;
+    FT_UInt   result;
+
+    /* try to remove "count" nodes from the list */
+    if ( first == NULL )  /* empty list! */
+      return 0;
+
+    /* go to last node - it's a circular list */
+    node = FTC_NODE__PREV(first);
+    for ( result = 0; result < count; )
+    {
+      FTC_Node  prev = FTC_NODE__PREV(node);
+
+
+     /* don't touch locked nodes */
+      if ( node->ref_count <= 0 )
+      {
+        ftc_node_destroy( node, manager );
+        result++;
+      }
+
+      if ( prev == manager->nodes_list )
+        break;
+
+      node = prev;
+    }
+    return  result;
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FTC_Manager_RemoveFaceID( FTC_Manager  manager,
+                            FTC_FaceID   face_id )
+  {
+    FT_UInt  nn;
+
+   /* this will remove all FTC_SizeNode that correspond to
+    * the face_id as well
+    */
+    FTC_MruList_RemoveSelection( &manager->faces, NULL, face_id );
+
+    for ( nn = 0; nn < manager->num_caches; nn++ )
+      FTC_Cache_RemoveFaceID( manager->caches[nn], face_id );
+  }
+
+
+  /* documentation is in ftcmanag.h */
+
+  FT_EXPORT_DEF( void )
+  FTC_Node_Unref( FTC_Node     node,
+                  FTC_Manager  manager )
+  {
+    if ( node && (FT_UInt)node->cache_index < manager->num_caches )
+      node->ref_count--;
+  }
+
+
+/* END */
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -545,6 +545,10 @@
     FT_UShort  glyph_sid;
 
 
+    /* CID-keyed fonts don't have glyph names */
+    if ( !cff->charset.sids )
+      return -1;
+
     /* check range of standard char code */
     if ( charcode < 0 || charcode > 255 )
       return -1;
@@ -662,8 +666,6 @@
     {
       CFF_Font cff = (CFF_Font)(face->extra.data);
 
-
-      /* XXX: What about CID-keyed fonts? */
 
       bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
       achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );
--- a/src/sfnt/ttcmap0.c
+++ b/src/sfnt/ttcmap0.c
@@ -392,10 +392,13 @@
       else
       {
         /* a 16-bit character code */
-        p  += char_hi * 2;                          /* jump to key entry  */
-        sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) );  /* jump to sub-header */
 
-        /* check that the hi byte isn't a valid one-byte value */
+        /* jump to key entry  */
+        p  += char_hi * 2;
+        /* jump to sub-header */
+        sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) );
+
+        /* check that the high byte isn't a valid one-byte value */
         if ( sub == subs )
           goto Exit;
       }
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -12,7 +12,7 @@
 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
 /*  this file you indicate that you have read the license and              */
 /*  understand and accept it fully.                                        */
-/*            s                                                             */
+/*                                                                         */
 /***************************************************************************/
 
 
@@ -590,14 +590,15 @@
     }
 
     /* Compute root ascender, descender, text height, and max_advance */
-    metrics->ascender    = FT_PIX_ROUND( FT_MulFix( face->root.ascender,
-                                                       metrics->y_scale ) );
-    metrics->descender   = FT_PIX_ROUND( FT_MulFix( face->root.descender,
-                                                       metrics->y_scale ) );
-    metrics->height      = FT_PIX_ROUND( FT_MulFix( face->root.height,
-                                                       metrics->y_scale ) );
-    metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width,
-                                                       metrics->x_scale ) );
+    metrics->ascender =
+      FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) );
+    metrics->descender =
+      FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) );
+    metrics->height =
+      FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) );
+    metrics->max_advance =
+      FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width,
+                               metrics->x_scale ) );
 
 
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS