shithub: freetype+ttf2subf

Download patch

ref: 14183ea0f8b9c021400d748d7311ec2a907e9f8d
parent: c3b21608699a72698d382ad44c5f9fd6946ce43c
author: David Turner <[email protected]>
date: Wed Dec 5 10:59:33 EST 2001

First of all, a big thanks to Werner and Antoine for their latest work !!

    * src/pshinter/pshalgo2.c (psh2_hint_table_init),
      src/pshinter/pshalgo1.c (psh1_hint_table_init): removed compiler
      warnings

    * include/freetype/cache/*, src/cache/*: yet another massive rewrite of
    the caching sub-system, in order to both increase performance and allow
    simpler cache sub-classing. As an example, the code for the image and
    sbit caches is now much simpler

    I still need to update the documentation in www/freetype2/docs/cache.html
    to reflect the new design though..

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2001-12-05  David Turner  <[email protected]>
+
+    First of all, a big thanks to Werner and Antoine for their latest work !!
+    
+    * src/pshinter/pshalgo2.c (psh2_hint_table_init),
+      src/pshinter/pshalgo1.c (psh1_hint_table_init): removed compiler
+      warnings
+
+    * include/freetype/cache/*, src/cache/*: yet another massive rewrite of
+    the caching sub-system, in order to both increase performance and allow
+    simpler cache sub-classing. As an example, the code for the image and
+    sbit caches is now much simpler
+
+    I still need to update the documentation in www/freetype2/docs/cache.html
+    to reflect the new design though..
+
+
 2001-12-05  David Krause  <[email protected]>
 
 	* docs/license.txt: s/X Windows/X Window System/.
--- /dev/null
+++ b/include/freetype/cache/ftccache.h
@@ -1,0 +1,251 @@
+#ifndef __FT_CACHE_CACHE_H__
+#define __FT_CACHE_CACHE_H__
+
+FT_BEGIN_HEADER
+
+  /* handle to cache object */
+  typedef struct FTC_CacheRec_*  FTC_Cache;
+
+
+  /* handle to cache class */
+  typedef const struct FTC_Cache_ClassRec_*  FTC_Cache_Class;
+
+
+ /* handle to cache node family */
+  typedef struct FTC_FamilyRec_*    FTC_Family;
+
+
+ /* handle to cache root query */
+  typedef struct FTC_QueryRec_*  FTC_Query;
+  
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                   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_Node   mru_next;     /* circular mru list pointer           */
+    FTC_Node   mru_prev;     /* circular mru list pointer           */
+    FTC_Node   link;         /* used for hashing..                  */
+    FT_UInt32  hash;         /* used for hashing too..              */
+    FT_UShort  fam_index;    /* index of family 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))
+
+ /* can be used as a FTC_Node_DoneFunc */
+  FT_EXPORT(void)
+  ftc_node_done( FTC_Node   node,
+                 FTC_Cache  cache );
+
+
+ /* reserved for manager's use */
+  FT_EXPORT(void)
+  ftc_node_destroy( FTC_Node     node,
+                    FTC_Manager  manager );
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                   CACHE QUERY DEFINITIONS                     *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+ /* structure modelling a cache node query. the following fields must    */
+ /* all be set by the @FTC_Family_CompareFunc method of a cache's family */
+ /* list                                                                 */
+ /*                                                                      */
+  typedef struct FTC_QueryRec_
+  {
+    FTC_Family  family;
+    FT_UFast    hash;
+
+  } FTC_QueryRec;
+
+
+#define  FTC_QUERY(x)    ((FTC_Query)(x))
+#define  FTC_QUERY_P(x)  ((FTC_Query*)(x))
+
+
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                   CACHE FAMILY DEFINITIONS                    *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  typedef struct FTC_FamilyRec_
+  {
+    FT_LruNodeRec  lru;
+    FTC_Cache      cache;
+    FT_UInt        num_nodes;
+    FT_UInt        fam_index;
+    
+  } FTC_FamilyRec;
+
+#define  FTC_FAMILY(x)    ((FTC_Family)(x))
+#define  FTC_FAMILY_P(x)  ((FTC_Family*)(x))
+
+
+ /* must be called by any FTC_Node_InitFunc routine */
+  FT_EXPORT(FT_Error)
+  ftc_family_init( FTC_Family  family,
+                   FTC_Query   query,
+                   FTC_Cache   cache );
+
+
+ /* can be used as a FTC_Family_DoneFunc, otherwise, must be called */
+ /* by any family finalizer function..                              */
+  FT_EXPORT(void)
+  ftc_family_done( FTC_Family  family );
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                       CACHE DEFINITIONS                       *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+ /* each cache really implements a dynamic hash table to manage its nodes */
+  typedef struct  FTC_CacheRec_
+  {
+    FTC_Manager          manager;
+    FT_Memory            memory;
+    FTC_Cache_Class      clazz;
+
+    FT_UInt              cache_index;  /* in manager's table         */
+    FT_Pointer           cache_data;   /* used by cache node methods */
+
+    FT_UFast             nodes;
+    FT_UFast             size;
+    FTC_Node*            buckets;
+
+    FT_LruList_ClassRec  family_class;
+    FT_LruList           families;
+
+  } FTC_CacheRec;
+
+
+#define  FTC_CACHE(x)    ((FTC_Cache)(x))
+#define  FTC_CACHE_P(x)  ((FTC_Cache*)(x))
+
+
+  /* initialize a given cache */
+  typedef FT_Error  (*FTC_Cache_InitFunc)( FTC_Cache  cache );
+
+  /* clear a cache */
+  typedef void      (*FTC_Cache_ClearFunc)( FTC_Cache  cache );
+  
+ /* finalize a given cache */
+  typedef void      (*FTC_Cache_DoneFunc)( FTC_Cache   cache );
+
+
+  typedef FT_Error  (*FTC_Family_InitFunc)( FTC_Family  family,
+                                            FTC_Query   query,
+                                            FTC_Cache   cache );
+
+  typedef FT_Int    (*FTC_Family_CompareFunc)( FTC_Family  family,
+                                               FTC_Query   query );
+
+  typedef void      (*FTC_Family_DoneFunc)( FTC_Family  family,
+                                            FTC_Cache   cache );
+                                            
+ /* initialize a new cache node */
+  typedef FT_Error  (*FTC_Node_InitFunc)( FTC_Node    node,
+                                          FT_Pointer  type,
+                                          FTC_Cache   cache );
+
+  /* compute the weight of a given cache node */
+  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 );
+
+  /* finalize a given cache node */
+  typedef void      (*FTC_Node_DoneFunc)( FTC_Node   node,
+                                          FTC_Cache  cache );
+
+
+  typedef struct  FTC_Cache_ClassRec_
+  {
+    FT_UInt                 cache_size;
+    FTC_Cache_InitFunc      cache_init;
+    FTC_Cache_ClearFunc     cache_clear;
+    FTC_Cache_DoneFunc      cache_done;
+
+    FT_UInt                 family_size;
+    FTC_Family_InitFunc     family_init;
+    FTC_Family_CompareFunc  family_compare;
+    FTC_Family_DoneFunc     family_done;
+    
+    FT_UInt                 node_size;
+    FTC_Node_InitFunc       node_init;
+    FTC_Node_WeightFunc     node_weight;
+    FTC_Node_CompareFunc    node_compare;
+    FTC_Node_DoneFunc       node_done;
+  
+  } FTC_Cache_ClassRec;
+
+  /* */
+
+  /* can be used directly as FTC_Cache_DoneFunc(), or called by custom */
+  /* cache finalizers                                                  */
+  FT_EXPORT( void )
+  ftc_cache_done( FTC_Cache  cache );
+
+
+  /* can be used directly as FTC_Cache_ClearFunc(), or called by custom */
+  /* cache clear routines..                                             */
+  FT_EXPORT( void )
+  ftc_cache_clear( FTC_Cache  cache );
+
+
+  /* initalize the hash table within the cache */
+  FT_EXPORT( FT_Error )
+  ftc_cache_init( FTC_Cache  cache );
+
+
+ /* can be called when the key's hash value has been computed */
+  FT_EXPORT(FT_Error)
+  ftc_cache_lookup( FTC_Cache    cache,
+                    FTC_Query    query,
+                    FTC_Node    *anode );
+
+
+
+ /* */
+
+FT_END_HEADER
+
+#endif /* __FT_CACHE_CACHE_H__ */
--- a/include/freetype/cache/ftcchunk.h
+++ /dev/null
@@ -1,168 +1,0 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftcchunk.h                                                             */
-/*                                                                         */
-/*    FreeType chunk cache (specification).                                */
-/*                                                                         */
-/*  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.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Important: The functions defined in this file are only used to        */
-  /*            implement an abstract chunk cache class.  You need to      */
-  /*            provide additional logic to implement a complete cache.    */
-  /*            For example, see `ftcmetrx.h' and `ftcmetrx.c' which       */
-  /*            implement a glyph metrics cache based on this code.        */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*********                                                       *********/
-  /*********             WARNING, THIS IS BETA CODE.               *********/
-  /*********                                                       *********/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-#ifndef __FTCCHUNK_H__
-#define __FTCCHUNK_H__
-
-
-#include <ft2build.h>
-#include FT_CACHE_H
-#include FT_CACHE_MANAGER_H
-
-
-FT_BEGIN_HEADER
-
-
-  /* maximum number of chunk sets in a given chunk cache */
-#define FTC_MAX_CHUNK_SETS  16
-
-
-  typedef struct FTC_ChunkNodeRec_*   FTC_ChunkNode;
-  typedef struct FTC_ChunkSetRec_*    FTC_ChunkSet;
-  typedef struct FTC_ChunkCacheRec_*  FTC_ChunkCache;
-
-  typedef struct  FTC_ChunkNodeRec_
-  {
-    FTC_NodeRec   node;
-    FTC_ChunkSet  cset;
-    FT_UShort     item_count;
-    FT_UShort     item_start;
-    FT_Byte*      items;
-
-  } FTC_ChunkNodeRec;
-
-#define FTC_CHUNK_NODE( x )  ((FTC_ChunkNode)( x ))
-
-  /* a chunk set is used to categorize chunks of a given type */
-  typedef struct  FTC_ChunkSetRec_
-  {
-    FT_LruNodeRec   lru;
-    FT_UFast        hash;
-    FTC_ChunkCache  ccache;
-    FT_Fast         num_chunks;
-    FT_UInt         item_total;   /* total number of glyphs in set   */
-    FT_UInt         item_size;    /* size of each glyph item in set  */
-    FT_UInt         item_count;   /* number of glyph items per chunk */
-  
-  } FTC_ChunkSetRec;
-
-#define FTC_CHUNK_SET( x )  ((FTC_ChunkSet)( x ))
-
-#define FTC_CHUNK_SET_MEMORY( x )  (( x )->ccache->cache.memory)
-
-  /* the abstract chunk cache class */
-  typedef struct  FTC_ChunkCacheRec_
-  {
-    FTC_CacheRec  cache;
-    FT_LruList    cset_lru;  /* LRU list of chunk sets */
-  
-  } FTC_ChunkCacheRec;
-
-#define FTC_CHUNK_CACHE( x )  ((FTC_ChunkCache)( x ))
-
-
-  typedef struct  FTC_ChunkQueryRec_
-  {
-    /* input */
-    FT_UInt       gindex;      /* glyph index */
-
-    /* output */
-    FTC_ChunkSet  cset;
-  
-  } FTC_ChunkQueryRec, *FTC_ChunkQuery;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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.                                           */
-  /*                                                                       */
-
-  FT_EXPORT( FT_Error )
-  ftc_chunk_node_init( FTC_ChunkNode  node,
-                       FTC_ChunkSet   cset,
-                       FT_UInt        index,
-                       FT_Bool        alloc );
-
-  /* chunk set objects */
-
-  FT_EXPORT( void )
-  ftc_chunk_node_done( FTC_ChunkNode  node );
-
-
-  FT_EXPORT( FT_Error )
-  ftc_chunk_set_init( FTC_ChunkSet    cset,
-                      FT_UInt         item_size,
-                      FT_UInt         item_count,
-                      FT_UInt         item_total,
-                      FTC_ChunkCache  cache );
-
-  FT_EXPORT( void )
-  ftc_chunk_set_done( FTC_ChunkSet  cset );
-
-
-  /* chunk cache objects */
-
-  FT_EXPORT( FT_Error )
-  ftc_chunk_cache_init( FTC_ChunkCache    cache,
-                        FT_LruList_Class  cset_class );
-
-  FT_EXPORT( void )
-  ftc_chunk_cache_done( FTC_ChunkCache  cache );
-
-
-  FT_EXPORT( FT_Error )
-  ftc_chunk_cache_lookup( FTC_ChunkCache  cache,
-                          FTC_ChunkQuery  query,
-                          FTC_ChunkNode  *anode );
-
- /* */
-
-FT_END_HEADER
-
-#endif /* __FTCCHUNK_H__ */
-
-
-/* END */
--- a/include/freetype/cache/ftcglyph.h
+++ b/include/freetype/cache/ftcglyph.h
@@ -64,86 +64,92 @@
 FT_BEGIN_HEADER
 
 
-  /* each glyph set is caracterized by a "glyph set type" which must be */
-  /* defined by sub-classes                                             */
-  typedef struct FTC_GlyphSetRec_*  FTC_GlyphSet;
+ /* each glyph set is caracterized by a "glyph set type" which must be */
+ /* defined by sub-classes..                                           */
+  typedef struct FTC_GlyphFamilyRec_*     FTC_GlyphFamily;
 
-  /* handle to a glyph cache node */
-  typedef struct FTC_GlyphNodeRec_*  FTC_GlyphNode;
+ /* handle to a glyph cache node */
+  typedef struct FTC_GlyphNodeRec_*       FTC_GlyphNode;
 
-  /* a glyph cache; its nodes are all glyph-specific */
-  typedef struct FTC_GlyphCacheRec_*  FTC_GlyphCache;
 
-  /* glyph sets class handle */
-  typedef const struct FTC_GlyphSet_ClassRec_*  FTC_GlyphSet_Class;
-
-
-  /* Size should be 24 bytes on 32-bit machines.                      */
-  /* Note that the node's hash is ((gset->hash << 16) | glyph_index); */
-  /* this _must_ be set properly by the glyph node initializer.       */
-  /*                                                                  */
+ /* size should be 24 + chunk size on 32-bit machines               */
+ /* note that the node's hash is ((gfam->hash << 16) | glyph_index) */
+ /* this _must_ be set properly by the glyph node initializer..     */
+ /*                                                                 */
   typedef struct  FTC_GlyphNodeRec_
   {
     FTC_NodeRec   node;
-    FTC_GlyphSet  gset;
+    FT_UShort     item_count;
+    FT_UShort     item_start;
 
   } FTC_GlyphNodeRec;
 
-#define FTC_GLYPH_NODE( x )    ((FTC_GlyphNode)( x ))
-#define FTC_GLYPH_NODE_P( x )  ((FTC_GlyphNode*)( x ))
+#define  FTC_GLYPH_NODE(x)    ((FTC_GlyphNode)(x))
+#define  FTC_GLYPH_NODE_P(x)  ((FTC_GlyphNode*)(x))
 
 
-  /* The glyph set structure.  Each glyph set is used to model a set of    */
-  /* glyphs of the same "type".  The type itself is defined in             */
-  /* sub-classes.                                                          */
-  /*                                                                       */
-  /* For example, the "image cache" uses face_id + character_pixel_sizes + */
-  /* image_format to characterize glyph sets.                              */
-  /*                                                                       */
-  /* A pure "master outlines" cache would only use face_id, etc.           */
-  /*                                                                       */
-  typedef struct  FTC_GlyphSetRec_
+
+  typedef struct  FTC_GlyphQueryRec_
   {
-    FT_LruNodeRec   lru;         /* glyph sets are LRU nodes within */
-    FTC_GlyphCache  gcache;      /* parent cache                    */
-    FT_UFast        hash;        /* must be set by initializer!     */
-    FT_Fast         num_glyphs;  /* destroyed when 0                */
+    FTC_QueryRec  query;
+    FT_UInt       gindex;
 
-  } FTC_GlyphSetRec;
+  } FTC_GlyphQueryRec, *FTC_GlyphQuery;
 
-#define FTC_GLYPH_SET( x )    ((FTC_GlyphSet)( x ))
-#define FTC_GLYPH_SET_P( x )  ((FTC_GlyphSet*)( x ))
+#define FTC_GLYPH_QUERY(x)  ((FTC_GlyphQuery)(x))
 
-#define FTC_GLYPH_SET_MEMORY( x )  (( x )->gcache->cache.memory)
 
 
-  /* retrieve glyph index of glyph node */
-#define FTC_GLYPH_NODE_GINDEX( x ) \
-          ((FT_UInt)(FTC_GLYPH_NODE( x )->node.hash & 0xFFFF))
 
-  /* the abstract glyph cache object */
-  typedef struct  FTC_GlyphCacheRec_
+ /* a glyph set is used to categorize glyphs of a given type */
+  typedef struct FTC_GlyphFamilyRec_
   {
-    FTC_CacheRec  cache;
-    FT_LruList    gset_lru;   /* LRU list of glyph sets */
+    FTC_FamilyRec  family;
+    FT_UInt32      hash;
+    FT_UInt        item_total;   /* total number of glyphs in family */
+    FT_UInt        item_count;   /* number of glyph items per node   */
 
-  } FTC_GlyphCacheRec;
+  } FTC_GlyphFamilyRec;
 
-#define FTC_GLYPH_CACHE( x )    ((FTC_GlyphCache)( x ))
-#define FTC_GLYPH_CACHE_P( x )  ((FTC_GlyphCache*)( x ))
 
+#define  FTC_GLYPH_FAMILY(x)     ((FTC_GlyphFamily)(x))
+#define  FTC_GLYPH_FAMILY_P(x)   ((FTC_GlyphFamily*)(x))
 
-  typedef struct  FTC_GlyphQueryRec_
-  {
-    /* input */
-    FT_UInt       gindex;
-   
-    /* output */
-    FTC_GlyphSet  gset;
+#define  FTC_GLYPH_FAMILY_MEMORY(x)  FTC_FAMILY(x)->cache->memory
 
-  } FTC_GlyphQueryRec, *FTC_GlyphQuery;
+/* each glyph node contains a 'chunk' of glyph items */
+/* translate a glyph index into a chunk index        */
+#define  FTC_GLYPH_FAMILY_CHUNK(gfam,gindex)   \
+      ( (gindex) / FTC_GLYPH_FAMILY(gfam)->item_count )
 
+/* find a glyph index's chunk, and return its start index */
+/*                                                        */
+#define  FTC_GLYPH_FAMILY_START(gfam,gindex)    \
+      ( FTC_GLYPH_FAMILY_CHUNK(gfam,gindex) * FTC_GLYPH_FAMILY(gfam)->item_count )
 
+/* compute a glyph request's hash value */
+/*                                      */
+#define  FTC_GLYPH_FAMILY_HASH(gfam,gindex)                           \
+      ((FT_UFast)( (FTC_GLYPH_FAMILY(gfam)->hash << 16) |             \
+                   (FTC_GLYPH_FAMILY_CHUNK(gfam,gindex) & 0xFFFF) ))
+
+/* must be called in a FTC_Family_CompareFunc to update the query */
+/* whenever a glyph set is matched in the lookup.. or when it     */
+/* is created                                                     */
+/*                                                                */
+#define  FTC_GLYPH_FAMILY_FOUND(gfam,gquery)                                  \
+           do {                                                               \
+             FTC_QUERY(gquery)->family = FTC_FAMILY(gfam);                    \
+             FTC_QUERY(gquery)->hash   =                                      \
+                FTC_GLYPH_FAMILY_HASH(gfam,FTC_GLYPH_QUERY(gquery)->gindex);  \
+           } while (0)
+
+
+/* retrieve glyph index of glyph node */
+#define  FTC_GLYPH_NODE_GINDEX(x)  \
+             ((FT_UInt)(FTC_GLYPH_NODE(x)->node.hash & 0xFFFF))
+
+
   /*************************************************************************/
   /*                                                                       */
   /* These functions are exported so that they can be called from          */
@@ -153,44 +159,42 @@
 
   /* must be called by derived FTC_Node_InitFunc routines */
   FT_EXPORT( void )
-  ftc_glyph_node_init( FTC_GlyphNode  node,
-                       FT_UInt        gindex,  /* glyph index for node */
-                       FTC_GlyphSet   gset );
+  ftc_glyph_node_init( FTC_GlyphNode     node,
+                       FT_UInt           gindex,  /* glyph index for node */
+                       FTC_GlyphFamily   gfam );
 
+  /* returns TRUE iff the query's glyph index correspond to the node  */
+  /* this assume that the "family" and "hash" fields of the query are */
+  /* already correctly set..                                          */
+  /*                                                                  */
+  FT_EXPORT( FT_Bool )
+  ftc_glyph_node_compare( FTC_GlyphNode    gnode,
+                          FTC_GlyphQuery   gquery );
+
+
   /* must be called by derived FTC_Node_DoneFunc routines */
   FT_EXPORT( void )
-  ftc_glyph_node_done( FTC_GlyphNode  node );
+  ftc_glyph_node_done( FTC_GlyphNode  node,
+                       FTC_Cache      cache );
 
 
-  /* can be used as an FTC_LruNode_InitFunc or called by sub-classes */
+ /* must be called by derived FTC_Family_InitFunc, calls "ftc_family_init" */
   FT_EXPORT( FT_Error )
-  ftc_glyph_set_init( FTC_GlyphSet  gset,
-                      FT_LruList    list );
+  ftc_glyph_family_init( FTC_GlyphFamily  gfam,
+                         FT_UInt32        hash,
+                         FT_UInt          item_count,
+                         FT_UInt          item_total,
+                         FTC_GlyphQuery   gquery,
+                         FTC_Cache        cache );
 
-  /* can be used as an FTC_LruNode_DoneFunc or called by sub-classes */
-  FT_EXPORT( void )
-  ftc_glyph_set_done( FTC_GlyphSet  gset );
 
-
-  /* can be used as an FTC_Cache_DoneFunc or called by sub-classes */
   FT_EXPORT( void )
-  ftc_glyph_cache_done( FTC_GlyphCache  cache );
+  ftc_glyph_family_done( FTC_GlyphFamily  gfam );
 
-  /* must be called in an FTC_Cache_InitFunc! */
-  FT_EXPORT( FT_Error )
-  ftc_glyph_cache_init( FTC_GlyphCache    cache,
-                        FT_LruList_Class  gset_class );
 
-  /* can be called directly or from sub-classes */
-  FT_EXPORT( FT_Error )
-  ftc_glyph_cache_lookup( FTC_GlyphCache  cache,
-                          FTC_GlyphQuery  query,
-                          FTC_GlyphNode  *anode );
 
-
+ /* */
+ 
 FT_END_HEADER
 
-#endif /* __FTCGLYPH_H__ */
-
-
-/* END */
+#endif /* __FTC_GLYPH_H__ */
--- a/include/freetype/cache/ftcimage.h
+++ b/include/freetype/cache/ftcimage.h
@@ -70,6 +70,7 @@
                                    ftc_image_flag_monochrome
   /* anti-aliased bitmap */
 #define ftc_image_grays            ftc_image_format_bitmap
+
   /* scaled outline */
 #define ftc_image_outline          ftc_image_format_outline
 
@@ -77,9 +78,130 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Struct>                                                              */
+  /*    FTC_ImageDesc                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure used to describe a given glyph image category.  */
+  /*    note that this is different from @FTC_Image_Desc                   */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    size    :: An FTC_SizeRec used to describe the glyph's face &      */
+  /*               size.                                                   */
+  /*                                                                       */
+  /*    type    :: The glyph image's type. note that it's a 32-bit uint    */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*   this type deprecates @FTC_Image_Desc                                */
+  /*                                                                       */
+  typedef struct  FTC_ImageDesc_
+  {
+    FTC_FontRec  font;
+    FT_UInt32    type;
+
+  } FTC_ImageDesc;
+
+ /* */
+#define  FTC_IMAGE_DESC_COMPARE( d1, d2 )                        \
+             ( FTC_FONT_COMPARE( &(d1)->font, &(d2)->font ) &&   \
+               (d1)->type == (d2)->type         )
+
+#define  FTC_IMAGE_DESC_HASH(d)                         \
+             (FT_UFast)( FTC_FONT_HASH(&(d)->font) ^    \
+                         ((d)->type << 4)    )
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FTC_ImageCache                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to an glyph image cache object.  They are designed to     */
+  /*    hold many distinct glyph images, while not exceeding a certain     */
+  /*    memory threshold.                                                  */
+  /*                                                                       */
+  typedef struct FTC_ImageCacheRec_*  FTC_ImageCache;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FTC_ImageCache_New                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Creates a new glyph image cache.                                   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    manager :: The parent manager for the image cache.                 */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    acache  :: A handle to the new glyph image cache object.           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FTC_ImageCache_New( FTC_Manager      manager,
+                      FTC_ImageCache  *acache );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FTC_ImageCache_Lookup                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Retrieves a given glyph image from a glyph image cache             */
+  /*    and 'acquire' it. This prevents the glyph image from being         */
+  /*    flushed out of the cache, until @FTC_Image_Cache_Release is        */
+  /*    called                                                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    cache  :: A handle to the source glyph image cache.                */
+  /*                                                                       */
+  /*    desc   :: A pointer to a glyph image descriptor.                   */
+  /*                                                                       */
+  /*    gindex :: The glyph index to retrieve.                             */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    aglyph :: The corresponding FT_Glyph object.  0 in case of         */
+  /*              failure.                                                 */
+  /*                                                                       */
+  /*    anode  :: an opaque cache node pointer that will be used           */
+  /*              to release the glyph once it becomes unuseful.           */
+  /*              can be NULL, in which case this function will            */
+  /*              have the same effect than @FTC_Image_Cache_Lookup        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The returned glyph is owned and managed by the glyph image cache.  */
+  /*    Never try to transform or discard it manually!  You can however    */
+  /*    create a copy with FT_Glyph_Copy() and modify the new one.         */
+  /*                                                                       */
+  /*    if 'anode' is NULL                                                 */
+  /*                                                                       */
+  /*    Because the glyph image cache limits the total amount of memory    */
+  /*    taken by the glyphs it holds, the returned glyph might disappear   */
+  /*    on a later invocation of this function!  It's a cache after all... */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FTC_ImageCache_Lookup( FTC_ImageCache  cache,
+                         FTC_ImageDesc*  desc,
+                         FT_UInt          gindex,
+                         FT_Glyph        *aglyph,
+                         FTC_Node        *anode );
+
+  /* */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
   /*    FTC_Image_Desc                                                     */
   /*                                                                       */
   /* <Description>                                                         */
+  /*    THIS TYPE IS DEPRECATED. USE @FTC_ImageDesc instead..              */
   /*    A simple structure used to describe a given glyph image category.  */
   /*                                                                       */
   /* <Fields>                                                              */
@@ -88,6 +210,9 @@
   /*                                                                       */
   /*    image_type :: The glyph image's type.                              */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*                                                                       */
+  /*                                                                       */
   typedef struct  FTC_Image_Desc_
   {
     FTC_FontRec  font;
@@ -96,16 +221,6 @@
   } FTC_Image_Desc;
 
 
- /* */
-#define FTC_IMAGE_DESC_COMPARE( d1, d2 )                    \
-          ( FTC_FONT_COMPARE( &(d1)->font, &(d2)->font ) && \
-            (d1)->image_type == (d2)->image_type         )
-
-#define FTC_IMAGE_DESC_HASH( d )                  \
-          (FT_UFast)( FTC_FONT_HASH(&(d)->font) ^ \
-                      ((d)->image_type << 4)    )
-
-
   /*************************************************************************/
   /*                                                                       */
   /* <Type>                                                                */
@@ -112,13 +227,12 @@
   /*    FTC_Image_Cache                                                    */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A handle to an glyph image cache object.  They are designed to     */
-  /*    hold many distinct glyph images, while not exceeding a certain     */
-  /*    memory threshold.                                                  */
+  /*    THIS TYPE IS DEPRECATED, USE @FTC_ImageCache instead               */
   /*                                                                       */
-  typedef struct FTC_Image_CacheRec_*  FTC_Image_Cache;
+  typedef FTC_ImageCache  FTC_Image_Cache;
 
 
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -125,6 +239,7 @@
   /*    FTC_Image_Cache_New                                                */
   /*                                                                       */
   /* <Description>                                                         */
+  /*    THIS FUNCTION IS DEPRECATED, USE @FTC_ImageCache_New instead       */
   /*    Creates a new glyph image cache.                                   */
   /*                                                                       */
   /* <Input>                                                               */
@@ -147,7 +262,7 @@
   /*    FTC_Image_Cache_Lookup                                             */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Retrieves a given glyph image from a glyph image cache.            */
+  /*    THIS FUNCTION IS DEPRECATED. USE @FTC_ImageCache_Lookup instead    */
   /*                                                                       */
   /* <Input>                                                               */
   /*    cache  :: A handle to the source glyph image cache.                */
@@ -172,6 +287,9 @@
   /*    taken by the glyphs it holds, the returned glyph might disappear   */
   /*    on a later invocation of this function!  It's a cache after all... */
   /*                                                                       */
+  /*    use @FTC_ImageCache_Lookup to "lock" the glyph as long as you      */
+  /*    need it..                                                          */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FTC_Image_Cache_Lookup( FTC_Image_Cache  cache,
                           FTC_Image_Desc*  desc,
@@ -178,9 +296,7 @@
                           FT_UInt          gindex,
                           FT_Glyph        *aglyph );
 
-
-  /* */
-
+ /* */
 
 FT_END_HEADER
 
--- a/include/freetype/cache/ftcmanag.h
+++ b/include/freetype/cache/ftcmanag.h
@@ -66,8 +66,8 @@
 #include <ft2build.h>
 #include FT_CACHE_H
 #include FT_CACHE_INTERNAL_LRU_H
+#include FT_CACHE_INTERNAL_CACHE_H
 
-
 FT_BEGIN_HEADER
 
 
@@ -81,23 +81,44 @@
 
 #define FTC_MAX_FACES_DEFAULT  2
 #define FTC_MAX_SIZES_DEFAULT  4
-#define FTC_MAX_BYTES_DEFAULT  100000L  /* 100kByte by default! */
+#define FTC_MAX_BYTES_DEFAULT  200000L  /* ~200 KB bytes by default */
 
   /* maximum number of caches registered in a single manager */
 #define FTC_MAX_CACHES         16
 
 
-  /* handle to cache object */
-  typedef struct FTC_CacheRec_*  FTC_Cache;
+  typedef struct FTC_FamilyEntryRec_
+  {
+    FTC_Family       family;
+    FTC_Cache        cache;
+    FT_UInt          index;
+    FT_UInt          link;
 
-  /* handle to cache class */
-  typedef const struct FTC_Cache_ClassRec_*  FTC_Cache_Class;
+  } FTC_FamilyEntryRec, *FTC_FamilyEntry;
 
-  /* handle to cache node */
-  typedef struct FTC_NodeRec_*  FTC_Node;
+#define  FTC_FAMILY_ENTRY_NONE  ((FT_UInt)-1)
 
+  typedef struct FTC_FamilyTableRec_
+  {
+    FT_UInt          count;
+    FT_UInt          size;
+    FTC_FamilyEntry  entries;
+    FT_UInt          free;
+  
+  } FTC_FamilyTableRec, *FTC_FamilyTable;
 
 
+  FT_LOCAL FT_Error 
+  ftc_family_table_alloc( FTC_FamilyTable   table,
+                          FT_Memory         memory,
+                          FTC_FamilyEntry  *aentry );
+
+
+  FT_LOCAL void 
+  ftc_family_table_free( FTC_FamilyTable  table,
+                         FT_UInt          index );
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Struct>                                                              */
@@ -146,6 +167,8 @@
     FT_Pointer          request_data;
     FTC_Face_Requester  request_face;
 
+    FTC_FamilyTableRec   families;
+
   } FTC_ManagerRec;
 
 
@@ -174,116 +197,6 @@
   FTC_Manager_Compress( FTC_Manager  manager );
 
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                   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_Node   mru_next;     /* circular mru list pointer          */
-    FTC_Node   mru_prev;     /* 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 ))
-
-
-  /* each cache really implements a dynamic hash table to manage its nodes */
-  typedef struct  FTC_CacheRec_
-  {
-    FTC_Manager      manager;
-    FT_Memory        memory;
-    FTC_Cache_Class  clazz;
-
-    FT_UInt          cache_index;  /* in manager's table         */
-    FT_Pointer       cache_data;   /* used by cache node methods */
-
-    FT_UFast         nodes;
-    FT_UFast         size;
-    FTC_Node*        buckets;
-
-  } FTC_CacheRec;
-
-
-#define FTC_CACHE( x )    ((FTC_Cache)( x ))
-#define FTC_CACHE_P( x )  ((FTC_Cache*)( x ))
-
-
-  /* initialize a given cache */
-  typedef FT_Error
-  (*FTC_Cache_InitFunc)( FTC_Cache  cache );
-  
-  /* finalize a given cache */
-  typedef void
-  (*FTC_Cache_DoneFunc)( FTC_Cache  cache );
-
-  /* initialize a new cache node */
-  typedef FT_Error
-  (*FTC_Node_InitFunc)( FTC_Node    node,
-                        FT_Pointer  type,
-                        FTC_Cache   cache );
-
-  /* compute the weight of a given cache node */
-  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 );
-
-  /* finalize a given cache node */
-  typedef void
-  (*FTC_Node_DoneFunc)( FTC_Node   node,
-                        FTC_Cache  cache );
-
-
-  typedef struct  FTC_Cache_ClassRec_
-  {
-    FT_UInt               cache_size;
-    FTC_Cache_InitFunc    cache_init;
-    FTC_Cache_DoneFunc    cache_done;
-    
-    FT_UInt               node_size;
-    FTC_Node_InitFunc     node_init;
-    FTC_Node_WeightFunc   node_weight;
-    FTC_Node_CompareFunc  node_compare;
-    FTC_Node_DoneFunc     node_done;
-  
-  } FTC_Cache_ClassRec;
-
-  /* */
-
-#define FTC_CACHE_RESIZE_TEST( c )       \
-          ( (c)->nodes*3 < (c)->size  || \
-            (c)->size*3  < (c)->nodes )      
-
-
   /* this must be used internally for the moment */
   FT_EXPORT( FT_Error )
   FTC_Manager_Register_Cache( FTC_Manager      manager,
@@ -291,37 +204,16 @@
                               FTC_Cache       *acache );
 
 
-  /* can be used directly as FTC_Cache_DoneFunc(), or called by custom */
-  /* cache finalizers                                                  */
-  FT_EXPORT( void )
-  ftc_cache_done( FTC_Cache  cache );
+ /* can be called to increment a node's reference count */
+  FT_EXPORT(void)
+  FTC_Node_Ref( FTC_Node     node,
+                FTC_Manager  manager );
 
-  /* initalize the hash table within the cache */
-  FT_EXPORT( FT_Error )
-  ftc_cache_init( FTC_Cache  cache );
 
-  /* can be used when FTC_CACHE_RESIZE_TEST returns TRUE after a node */
-  /* insertion                                                        */
-  FT_EXPORT( void )
-  ftc_cache_resize( FTC_Cache  cache );
-
-
-  /* can be called when the key's hash value has been computed */
-  FT_EXPORT( FT_Error )
-  ftc_cache_lookup_node( FTC_Cache   cache,
-                         FT_UFast    key_hash,
-                         FT_Pointer  key,
-                         FTC_Node   *anode );
-
-  /* can be called to increment a node's reference count */
-  FT_EXPORT( void )
-  ftc_node_ref( FTC_Node   node,
-                FTC_Cache  cache );
-
-  /* can be called to decrement a node's reference count */
-  FT_EXPORT( void )
-  ftc_node_unref( FTC_Node   node,
-                  FTC_Cache  cache );
+ /* can be called to decrement a node's reference count */
+  FT_EXPORT(void)
+  FTC_Node_Unref( FTC_Node     node,
+                  FTC_Manager  manager );
 
  /* */
 
--- a/include/freetype/cache/ftcsbits.h
+++ b/include/freetype/cache/ftcsbits.h
@@ -50,20 +50,6 @@
 
   /*************************************************************************/
   /*                                                                       */
-  /* <Type>                                                                */
-  /*    FTC_SBit_Cache                                                     */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A handle to a small bitmap cache.  These are special cache objects */
-  /*    used to store small glyph bitmaps (and anti-aliased pixmaps) in a  */
-  /*    much more efficient way than the traditional glyph image cache     */
-  /*    implemented by FTC_Image_Cache.                                    */
-  /*                                                                       */
-  typedef struct FTC_SBit_CacheRec_*  FTC_SBit_Cache;
-
-
-  /*************************************************************************/
-  /*                                                                       */
   /* <Struct>                                                              */
   /*    FTC_SBitRec                                                        */
   /*                                                                       */
@@ -112,9 +98,103 @@
   } FTC_SBitRec;
 
 
+
   /*************************************************************************/
   /*                                                                       */
+  /* <Type>                                                                */
+  /*    FTC_SBit_Cache                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a small bitmap cache.  These are special cache objects */
+  /*    used to store small glyph bitmaps (and anti-aliased pixmaps) in a  */
+  /*    much more efficient way than the traditional glyph image cache     */
+  /*    implemented by FTC_Image_Cache.                                    */
+  /*                                                                       */
+  typedef struct FTC_SBitCacheRec_*   FTC_SBitCache;
+  
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FTC_SBit_Cache                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    deprecated. please use @FTC_SBitCache instead                      */
+  /*                                                                       */
+  typedef FTC_SBitCache   FTC_SBit_Cache;
+
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
   /* <Function>                                                            */
+  /*    FTC_SBitCache_New                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Creates a new cache to store small glyph bitmaps.                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    manager :: A handle to the source cache manager.                   */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    acache  :: A handle to the new sbit cache.  NULL in case of error. */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FTC_SBitCache_New( FTC_Manager     manager,
+                     FTC_SBitCache  *acache );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FTC_SBitCache_Lookup                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Looks up a given small glyph bitmap in a given sbit cache and      */
+  /*    "lock" it to prevent its flushing from the cache until needed      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    cache  :: A handle to the source sbit cache.                       */
+  /*    desc   :: A pointer to the glyph image descriptor.                 */
+  /*    gindex :: The glyph index.                                         */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    sbit   :: A handle to a small bitmap descriptor.                   */
+  /*                                                                       */
+  /*    anode  :: an opaque cache node pointer that will be used           */
+  /*              to release the sbit once it becomes unuseful.            */
+  /*              can be NULL, in which case this function will            */
+  /*              have the same effect than @FTC_SBit_Cache_Lookup         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The small bitmap descriptor and its bit buffer are owned by the    */
+  /*    cache and should never be freed by the application.  They might    */
+  /*    as well disappear from memory on the next cache lookup, so don't   */
+  /*    treat them as persistent data.                                     */
+  /*                                                                       */
+  /*    The descriptor's `buffer' field is set to 0 to indicate a missing  */
+  /*    glyph bitmap.                                                      */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FTC_SBitCache_Lookup( FTC_SBitCache    cache,
+                        FTC_ImageDesc*   desc,
+                        FT_UInt          gindex,
+                        FTC_SBit        *sbit,
+                        FTC_Node        *anode );
+
+
+  /* */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
   /*    FTC_SBit_Cache_New                                                 */
   /*                                                                       */
   /* <Description>                                                         */
@@ -167,9 +247,6 @@
                          FTC_Image_Desc*  desc,
                          FT_UInt          gindex,
                          FTC_SBit        *sbit );
-
-
-  /* */
 
 
 FT_END_HEADER
--- a/include/freetype/cache/ftlru.h
+++ b/include/freetype/cache/ftlru.h
@@ -58,14 +58,11 @@
 #ifndef __FTLRU_H__
 #define __FTLRU_H__
 
-
 #include <ft2build.h>
 #include FT_FREETYPE_H
 
-
 FT_BEGIN_HEADER
 
-
   /* generic list key type */
   typedef FT_Pointer  FT_LruKey;
 
@@ -75,9 +72,8 @@
   /* list class handle */
   typedef const struct FT_LruList_ClassRec_*  FT_LruList_Class;
 
-  /* a list node handle */
-  typedef struct FT_LruNodeRec_*  FT_LruNode;
-  
+  /* an list node handle */
+  typedef struct  FT_LruNodeRec_*   FT_LruNode;
 
   /* the list node structure */
   typedef struct  FT_LruNodeRec_
@@ -96,7 +92,7 @@
     FT_LruNode         nodes;
     FT_UInt            max_nodes;
     FT_UInt            num_nodes;
-    FT_Pointer         user_data;
+    FT_Pointer         data;
 
   } FT_LruListRec;
 
@@ -103,18 +99,18 @@
 
   /* initialize a list list */
   typedef FT_Error  (*FT_LruList_InitFunc)( FT_LruList  list );
-  
-  /* finalize a list list */
+
+ /* finalize a list list */
   typedef void      (*FT_LruList_DoneFunc)( FT_LruList  list );
 
   /* this method is used to initialize a new list element node */
   typedef FT_Error  (*FT_LruNode_InitFunc)( FT_LruNode  node,
                                             FT_LruKey   key,
-                                            FT_LruList  list );
+                                            FT_Pointer  data );
 
   /* this method is used to finalize a given list element node */
   typedef void      (*FT_LruNode_DoneFunc)( FT_LruNode  node,
-                                            FT_LruList  list );
+                                            FT_Pointer  data );
 
   /* If defined, this method is called when the list if full        */
   /* during the lookup process -- it is used to change the contents */
@@ -122,7 +118,7 @@
   /* then `init_element()'.  Set it to 0 for default behaviour.     */
   typedef FT_Error  (*FT_LruNode_FlushFunc)( FT_LruNode  node,
                                              FT_LruKey   new_key,
-                                             FT_LruList  list );
+                                             FT_Pointer  data );
 
   /* If defined, this method is used to compare a list element node */
   /* with a given key during a lookup.  If set to 0, the `key'      */
@@ -129,7 +125,7 @@
   /* fields will be directly compared instead.                      */
   typedef FT_Bool   (*FT_LruNode_CompareFunc)( FT_LruNode  node,
                                                FT_LruKey   key,
-                                               FT_LruList  list );
+                                               FT_Pointer  data );
 
   /* A selector is used to indicate whether a given list element node */
   /* is part of a selection for FT_LruList_Remove_Selection().  The   */
@@ -137,7 +133,7 @@
   /* node is part of it.                                              */
   typedef FT_Bool    (*FT_LruNode_SelectFunc)( FT_LruNode  node,
                                                FT_Pointer  data,
-                                               FT_LruList  list );
+                                               FT_Pointer  list_data );
 
   /* LRU class */
   typedef struct  FT_LruList_ClassRec_
@@ -145,7 +141,7 @@
     FT_UInt                 list_size;
     FT_LruList_InitFunc     list_init;      /* optional */
     FT_LruList_DoneFunc     list_done;      /* optional */
-  
+
     FT_UInt                 node_size;
     FT_LruNode_InitFunc     node_init;     /* MANDATORY */
     FT_LruNode_DoneFunc     node_done;     /* optional  */
@@ -190,7 +186,7 @@
                                FT_Pointer             select_data );
 
  /* */
- 
+
 FT_END_HEADER
 
 #endif /* __FTLRU_H__ */
--- a/include/freetype/config/ftheader.h
+++ b/include/freetype/config/ftheader.h
@@ -467,7 +467,7 @@
 
 #define FT_CACHE_INTERNAL_LRU_H    <freetype/cache/ftlru.h>
 #define FT_CACHE_INTERNAL_GLYPH_H  <freetype/cache/ftcglyph.h>
-#define FT_CACHE_INTERNAL_CHUNK_H  <freetype/cache/ftcchunk.h>
+#define FT_CACHE_INTERNAL_CACHE_H  <freetype/cache/ftccache.h>
 
   /* now include internal headers definitions from <freetype/internal/...> */
 
--- a/include/freetype/ftcache.h
+++ b/include/freetype/ftcache.h
@@ -57,6 +57,37 @@
   /*   This section describes the FreeType 2 cache sub-system which is     */
   /*   stile in beta.                                                      */
   /*                                                                       */
+  /* <Order>                                                               */
+  /*   FTC_Manager                                                         */
+  /*   FTC_FaceID                                                          */
+  /*   FTC_Face_Requester                                                  */
+  /*                                                                       */
+  /*   FTC_Manager_New                                                     */
+  /*   FTC_Manager_Lookup_Face                                             */
+  /*   FTC_Manager_Lookup_Size                                             */
+  /*                                                                       */
+  /*   FTC_Node                                                            */
+  /*   FTC_Node_Unref                                                      */
+  /*                                                                       */
+  /*   FTC_Font                                                            */
+  /*   FTC_ImageDesc                                                       */
+  /*   FTC_ImageCache                                                      */
+  /*   FTC_ImageCache_New                                                  */
+  /*   FTC_ImageCache_Lookup                                               */
+  /*                                                                       */
+  /*   FTC_SBit                                                            */
+  /*   FTC_SBitCache                                                       */
+  /*   FTC_SBitCache_New                                                   */
+  /*   FTC_SBitCache_Lookup                                                */
+  /*                                                                       */
+  /*                                                                       */
+  /*   FTC_Image_Desc                                                      */
+  /*   FTC_Image_Cache                                                     */
+  /*   FTC_Image_Cache_Lookup                                              */
+  /*                                                                       */
+  /*   FTC_SBit_Cache                                                      */
+  /*   FTC_Sbit_Cache_Lookup                                               */
+  /*                                                                       */
   /*************************************************************************/
 
 
@@ -157,7 +188,6 @@
                        ((f)->pix_width << 8)          ^ \
                        ((f)->pix_height)              )
 
-
   /*************************************************************************/
   /*                                                                       */
   /* <Type>                                                                */
@@ -194,6 +224,26 @@
 
   /*************************************************************************/
   /*                                                                       */
+  /* <Type>                                                                */
+  /*    FTC_Node                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    an opaque handle to a cache node object. Each cache node is        */
+  /*    reference-counted. A node with a count of 0 might be flushed       */
+  /*    out of a full cache whenever a lookup request is performed         */
+  /*                                                                       */
+  /*    when you lookup nodes, you have the ability to "acquire" them,     */
+  /*    i.e. increment their reference count. This will prevent the node   */
+  /*    from being flushed out of the cache until you explicitely          */
+  /*    "release" it (see @FTC_Node_Release)                               */
+  /*                                                                       */
+  /*    see @FTC_BitsetCache_Lookup and @FTC_ImageCache_Lookup             */
+  /*                                                                       */
+  typedef struct FTC_NodeRec_*     FTC_Node;
+
+
+  /*************************************************************************/
+  /*                                                                       */
   /* <Function>                                                            */
   /*    FTC_Manager_New                                                    */
   /*                                                                       */
@@ -348,6 +398,24 @@
                            FTC_Font     font,
                            FT_Face     *aface,
                            FT_Size     *asize );
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FTC_Node_Unref                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    decrement a cache node's internal reference count. when the count  */
+  /*    reaches 0, it is not destroyed but becomes eligible for subsequent */
+  /*    cache flushes..                                                    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    node    :: cache node handle                                       */
+  /*    manager :: cache manager handle                                    */
+  /*                                                                       */
+  FT_EXPORT( void )
+  FTC_Node_Unref( FTC_Node     node,
+                  FTC_Manager  manager );
 
   /* */
 
--- a/src/autohint/ahhint.c
+++ b/src/autohint/ahhint.c
@@ -384,8 +384,8 @@
     ah_debug_disable_horz = no_horz_edges;
     ah_debug_disable_vert = no_vert_edges;
 #else
-    UNUSED( no_horz_edges );
-    UNUSED( no_vert_edges );
+    FT_UNUSED(no_horz_edges);
+    FT_UNUSED(no_vert_edges);    
 #endif
     /* AH_Interpolate_Blue_Edges( hinter ); -- doesn't seem to help      */
     /* reduce the problem of the disappearing eye in the `e' of Times... */
--- a/src/base/ftdbgmem.c
+++ b/src/base/ftdbgmem.c
@@ -662,8 +662,8 @@
 
 
 #else  /* !FT_DEBUG_MEMORY */
-
- /* ANSI C doesn't like empty source files */
+ 
+ /* ansi C doesn't like empty source files */
   extern const FT_Byte  _debug_mem_dummy = 0;
 
 #endif /* !FT_DEBUG_MEMORY */
--- a/src/cache/Jamfile
+++ b/src/cache/Jamfile
@@ -16,7 +16,7 @@
 
   if $(FT2_MULTI)
   {
-    _sources = ftlru ftcmanag ftcglyph ftcchunk ftcsbits ftcimage ;
+    _sources = ftlru ftcmanag ftccache ftcglyph ftcsbits ftcimage ;
   }
   else
   {
--- a/src/cache/ftcache.c
+++ b/src/cache/ftcache.c
@@ -21,8 +21,8 @@
 #include <ft2build.h>
 #include "ftlru.c"
 #include "ftcmanag.c"
+#include "ftccache.c"
 #include "ftcglyph.c"
-#include "ftcchunk.c"
 #include "ftcimage.c"
 #include "ftcsbits.c"
 
--- a/src/cache/ftcglyph.c
+++ b/src/cache/ftcglyph.c
@@ -27,77 +27,53 @@
 #include "ftcerror.h"
 
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                      GLYPH NODES                              *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
 
 
-#define FTC_GSET_HASH( gset, gindex )                                      \
-          ( (FT_UFast)( ( (gset)->hash << 16 ) | ( (gindex) & 0xFFFF ) ) )
-
-
-  /* create a new glyph node, setting its cache index and ref count */
+  /* create a new chunk node, setting its cache index and ref count */
   FT_EXPORT_DEF( void )
-  ftc_glyph_node_init( FTC_GlyphNode  gnode,
-                       FT_UInt        gindex,
-                       FTC_GlyphSet   gset )
+  ftc_glyph_node_init( FTC_GlyphNode     gnode,
+                       FT_UInt           gindex,
+                       FTC_GlyphFamily   gfam )
   {
-    gnode->gset      = gset;
-    gnode->node.hash = FTC_GSET_HASH( gset, gindex );
-    gset->num_glyphs++;
-  }
+    FT_UInt    len;
+    FT_UInt    start = FTC_GLYPH_FAMILY_START(gfam,gindex);
 
 
-  /* Important: This function is called from the cache manager to */
-  /* destroy a given cache node during `cache compression'.  The  */
-  /* second argument is always `cache.cache_data'.  Thus be       */
-  /* certain that the function FTC_Glyph_Cache_New() does indeed  */
-  /* set its `cache_data' field correctly, otherwise bad things   */
-  /* will happen!                                                 */
+    gnode->node.fam_index = (FT_UShort) gfam->family.fam_index;
+    gnode->node.hash      = FTC_GLYPH_FAMILY_HASH(gfam,gindex);
+    gnode->item_start     = (FT_UShort) start;
 
-  FT_EXPORT_DEF( void )
-  ftc_glyph_node_done( FTC_GlyphNode  gnode )
-  {
-    FTC_GlyphSet  gset = gnode->gset;
-    
+    len = gfam->item_total - start;
+    if ( len > gfam->item_count )
+      len = gfam->item_count;
 
-    if ( --gset->num_glyphs <= 0 )
-      FT_LruList_Remove( gset->gcache->gset_lru, (FT_LruNode)gset );
+    gnode->item_count = (FT_UShort) len;
+    gfam->family.num_nodes++;
   }
 
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                      GLYPH SETS                               *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  FT_EXPORT_DEF( FT_Error )
-  ftc_glyph_set_init( FTC_GlyphSet  gset,
-                      FT_LruList    lru )
+  FT_EXPORT_DEF( void )
+  ftc_glyph_node_done( FTC_GlyphNode  gnode,
+                       FTC_Cache      cache )
   {
-    FTC_GlyphCache  gcache = lru->user_data;
-    
+    /* finalize the node */
+    gnode->item_count = 0;
+    gnode->item_start = 0;
 
-    gset->gcache     = gcache;
-    gset->num_glyphs = 0;
-    
-    return 0;
-  }                      
+    ftc_node_done( FTC_NODE(gnode), cache );
+  }
 
 
-  FT_EXPORT_DEF( void )
-  ftc_glyph_set_done( FTC_GlyphSet  gset )
+  FT_EXPORT_DEF( FT_Bool )
+  ftc_glyph_node_compare( FTC_GlyphNode    gnode,
+                          FTC_GlyphQuery   gquery )
   {
-    /* for now, nothing to be done here */
-    FT_UNUSED( gset );
+    FT_UInt  fam_index = (FT_UInt) FTC_NODE(gnode)->fam_index;
+    FT_UInt  start     = (FT_UInt) gnode->item_start;
+    FT_UInt  count     = (FT_UInt) gnode->item_count;
+
+    return FT_BOOL( (FT_UInt)(gquery->gindex - start) < count &&
+                     gquery->query.family->fam_index == fam_index );
   }
 
 
@@ -104,66 +80,43 @@
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
-  /*****                      GLYPH CACHES                             *****/
+  /*****                      CHUNK SETS                               *****/
   /*****                                                               *****/
   /*************************************************************************/
   /*************************************************************************/
 
 
-  FT_EXPORT_DEF( void )
-  ftc_glyph_cache_done( FTC_GlyphCache  gcache )
-  {
-    /* remove all nodes in the cache */
-    ftc_cache_done( &gcache->cache );
-  
-    /* simply delete all remaining glyph sets */
-    if ( gcache->gset_lru )
-    {
-      FT_LruList_Destroy( gcache->gset_lru );
-      gcache->gset_lru = NULL;
-    }
-  }
-
-
   FT_EXPORT_DEF( FT_Error )
-  ftc_glyph_cache_init( FTC_GlyphCache    gcache,
-                        FT_LruList_Class  gset_class )
+  ftc_glyph_family_init( FTC_GlyphFamily  gfam,
+                         FT_UInt32        hash,
+                         FT_UInt          item_count,
+                         FT_UInt          item_total,
+                         FTC_GlyphQuery   gquery,
+                         FTC_Cache        cache )
   {
     FT_Error  error;
 
 
-    error = ftc_cache_init( FTC_CACHE( gcache ) );
-    if ( error )
-      goto Exit;
-        
-    error = FT_LruList_New( gset_class, 0, gcache,
-                            gcache->cache.memory,
-                            &gcache->gset_lru );
-  Exit:
+    error = ftc_family_init( FTC_FAMILY(gfam), FTC_QUERY(gquery), cache );
+    if (!error)
+    {
+      gfam->hash       = hash;
+      gfam->item_total = item_total;
+      gfam->item_count = item_count;
+
+      FTC_GLYPH_FAMILY_FOUND(gfam,gquery);
+    }
+
     return error;
   }
 
 
-  FT_EXPORT_DEF( FT_Error )
-  ftc_glyph_cache_lookup( FTC_GlyphCache  gcache,
-                          FTC_GlyphQuery  query,
-                          FTC_GlyphNode  *anode )
+  FT_EXPORT_DEF( void )
+  ftc_glyph_family_done( FTC_GlyphFamily  gfam )
   {
-    FT_LruNode    node;
-    FT_Error      error;
-    
-
-    error = FT_LruList_Lookup( gcache->gset_lru, query, &node );
-    if ( !error )
-    {
-      FTC_GlyphSet  gset = (FTC_GlyphSet)node;
-      FT_UFast      hash = FTC_GSET_HASH( gset, query->gindex );
-      
-      error = ftc_cache_lookup_node( FTC_CACHE( gcache ), hash, query,
-                                     FTC_NODE_P( anode ) );
-    }
-    return error;
+    ftc_family_done( FTC_FAMILY(gfam) );
   }
+
 
 
 /* END */
--- a/src/cache/ftcimage.c
+++ b/src/cache/ftcimage.c
@@ -41,27 +41,31 @@
 #define FTC_IMAGE_NODE_GINDEX( x )  FTC_GLYPH_NODE_GINDEX( x )
 
 
-  /* the glyph image set type */
-  typedef struct  FTC_ImageSetRec_
+  /* the glyph image query */
+  typedef struct  FTC_ImageQueryRec_
   {
-    FTC_GlyphSetRec  gset;
-    FTC_Image_Desc   description;
+    FTC_GlyphQueryRec  gquery;
+    FTC_ImageDesc      desc;
 
-  } FTC_ImageSetRec, *FTC_ImageSet;
+  } FTC_ImageQueryRec, *FTC_ImageQuery;
 
+#define  FTC_IMAGE_QUERY(x)  ((FTC_ImageQuery)(x))
 
-#define  FTC_IMAGE_SET( x )         ((FTC_ImageSet)( x ))
-#define  FTC_IMAGE_SET_MEMORY( x )  FTC_GLYPH_SET_MEMORY( &(x)->gset )
 
 
-  typedef struct  FTC_ImageQueryRec_
+  /* the glyph image set type */
+  typedef struct  FTC_ImageFamilyRec_
   {
-    FTC_GlyphQueryRec  glyph;
-    FTC_Image_Desc     desc;
+    FTC_GlyphFamilyRec  gfam;
+    FTC_ImageDesc       desc;
 
-  } FTC_ImageQueryRec, *FTC_ImageQuery;
+  } FTC_ImageFamilyRec, *FTC_ImageFamily;
 
 
+#define  FTC_IMAGE_FAMILY( x )         ((FTC_ImageFamily)( x ))
+#define  FTC_IMAGE_FAMILY_MEMORY( x )  FTC_GLYPH_FAMILY_MEMORY( &(x)->gfam )
+
+
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -73,7 +77,8 @@
 
   /* finalize a given glyph image node */
   FT_CALLBACK_DEF( void )
-  ftc_image_node_done( FTC_ImageNode  inode )
+  ftc_image_node_done( FTC_ImageNode  inode,
+                       FTC_Cache      cache )
   {
     if ( inode->glyph )
     {
@@ -80,58 +85,62 @@
       FT_Done_Glyph( inode->glyph );
       inode->glyph = NULL;
     }
+    ftc_glyph_node_done( FTC_GLYPH_NODE(inode), cache );
   }
 
 
+
   /* initialize a new glyph image node */
   FT_CALLBACK_DEF( FT_Error )
   ftc_image_node_init( FTC_ImageNode   inode,
-                       FTC_GlyphQuery  query )
+                       FTC_GlyphQuery  gquery,
+                       FTC_Cache       cache )
   {
-    FTC_ImageSet  iset = FTC_IMAGE_SET( query->gset );
-    FT_Error      error;
-    FT_Face       face;
-    FT_Size       size;
+    FTC_ImageFamily ifam = FTC_IMAGE_FAMILY( gquery->query.family );
+    FT_Error        error;
+    FT_Face         face;
+    FT_Size         size;
 
 
     /* initialize its inner fields */
-    ftc_glyph_node_init( FTC_GLYPH_NODE( inode ),
-                         query->gindex, query->gset );
+    ftc_glyph_node_init( FTC_GLYPH_NODE(inode),
+                         gquery->gindex,
+                         FTC_GLYPH_FAMILY(ifam) );
 
     /* we will now load the glyph image */
-    error = FTC_Manager_Lookup_Size( iset->gset.gcache->cache.manager,
-                                     &iset->description.font,
+    error = FTC_Manager_Lookup_Size( FTC_FAMILY(ifam)->cache->manager,
+                                     &ifam->desc.font,
                                      &face, &size );
     if ( !error )
     {
       FT_UInt  gindex      = FTC_GLYPH_NODE_GINDEX(inode);
       FT_UInt  load_flags  = FT_LOAD_DEFAULT;
-      FT_UInt  image_type  = iset->description.image_type;
+      FT_UInt  type        = ifam->desc.type;
 
 
-      if ( FTC_IMAGE_FORMAT( image_type ) == ftc_image_format_bitmap )
+      if ( FTC_IMAGE_FORMAT( type ) == ftc_image_format_bitmap )
       {
         load_flags |= FT_LOAD_RENDER;
-        if ( image_type & ftc_image_flag_monochrome )
+        if ( type & ftc_image_flag_monochrome )
           load_flags |= FT_LOAD_MONOCHROME;
 
         /* disable embedded bitmaps loading if necessary */
-        if ( image_type & ftc_image_flag_no_sbits )
+        if ( type & ftc_image_flag_no_sbits )
           load_flags |= FT_LOAD_NO_BITMAP;
       }
-      else if ( FTC_IMAGE_FORMAT( image_type ) == ftc_image_format_outline )
+      else if ( FTC_IMAGE_FORMAT( type ) == ftc_image_format_outline )
       {
         /* disable embedded bitmaps loading */
         load_flags |= FT_LOAD_NO_BITMAP;
 
-        if ( image_type & ftc_image_flag_unscaled )
+        if ( type & ftc_image_flag_unscaled )
           load_flags |= FT_LOAD_NO_SCALE;
       }
 
-      if ( image_type & ftc_image_flag_unhinted )
+      if ( type & ftc_image_flag_unhinted )
         load_flags |= FT_LOAD_NO_HINTING;
 
-      if ( image_type & ftc_image_flag_autohinted )
+      if ( type & ftc_image_flag_autohinted )
         load_flags |= FT_LOAD_FORCE_AUTOHINT;
 
       error = FT_Load_Glyph( face, gindex, load_flags );
@@ -157,7 +166,7 @@
     }
 
     /* in case of error */
-    ftc_glyph_node_done( FTC_GLYPH_NODE( inode ) );
+    ftc_glyph_node_done( FTC_GLYPH_NODE(inode), cache );
 
   Exit:
     return error;
@@ -206,19 +215,6 @@
   }
 
 
-  /* this function assumes that the desired node's glyph set has been */
-  /* set by a previous call to ftc_image_set_compare()                */
-  /*                                                                  */
-  FT_CALLBACK_DEF( FT_Bool )
-  ftc_image_node_compare( FTC_ImageNode   inode,
-                          FTC_ImageQuery  iquery )
-  {
-    /* only if same glyph index and image set description */
-    return FT_BOOL( iquery->glyph.gindex == FTC_IMAGE_NODE_GINDEX( inode ) &&
-                    iquery->glyph.gset   == inode->gnode.gset );
-  }
-
-
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -229,53 +225,51 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  ftc_image_set_init( FTC_ImageSet     iset,
-                      FTC_ImageQuery   query,
-                      FT_LruList       lru )
+  ftc_image_family_init( FTC_ImageFamily  ifam,
+                         FTC_ImageQuery   iquery,
+                         FTC_Cache        cache )
   {
-    ftc_glyph_set_init( &iset->gset, lru );
-    iset->description = query->desc;
+    FTC_Manager  manager = cache->manager;
+    FT_Error     error;
+    FT_Face      face;
 
-    /* now compute hash from description -- this is _very_ important */
-    iset->gset.hash   = FTC_IMAGE_DESC_HASH( &query->desc );
-    query->glyph.gset = FTC_GLYPH_SET( iset );
 
-    return 0;
+    ifam->desc = iquery->desc;
+
+    /* we need to compute "iquery.item_total" now */
+    error = FTC_Manager_Lookup_Face( manager,
+                                     iquery->desc.font.face_id,
+                                     &face );
+    if ( !error )
+    {
+      error = ftc_glyph_family_init( FTC_GLYPH_FAMILY(ifam),
+                                     FTC_IMAGE_DESC_HASH( &ifam->desc ),
+                                     1,
+                                     face->num_glyphs,
+                                     FTC_GLYPH_QUERY(iquery),
+                                     cache );
+    }
+
+    return error;
   }
 
 
   FT_CALLBACK_DEF( FT_Bool )
-  ftc_image_set_compare( FTC_ImageSet    iset,
-                         FTC_ImageQuery  iquery )
+  ftc_image_family_compare( FTC_ImageFamily  ifam,
+                            FTC_ImageQuery   iquery )
   {
     FT_Bool  result;
 
 
-    /* we must set iquery.glyph.gset for faster glyph node comparisons */
-    result = FT_BOOL( FTC_IMAGE_DESC_COMPARE( &iset->description,
-                                              &iquery->desc ) );
+    /* we must set iquery.glyph.gfam for faster glyph node comparisons */
+    result = FT_BOOL( FTC_IMAGE_DESC_COMPARE( &ifam->desc, &iquery->desc ) );
     if ( result )
-      iquery->glyph.gset = &iset->gset;
+      FTC_GLYPH_FAMILY_FOUND(ifam,iquery);
 
     return result;
   }
 
 
-  FT_CALLBACK_TABLE_DEF
-  const FT_LruList_ClassRec  ftc_image_set_class =
-  {
-    sizeof ( FT_LruListRec ),
-    (FT_LruList_InitFunc)   NULL,
-    (FT_LruList_DoneFunc)   NULL,
-
-    sizeof ( FTC_ImageSetRec ),
-    (FT_LruNode_InitFunc)   ftc_image_set_init,
-    (FT_LruNode_DoneFunc)   ftc_glyph_set_init,
-    (FT_LruNode_FlushFunc)  NULL,
-    (FT_LruNode_CompareFunc)ftc_image_set_compare
-  };
-
-
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -285,26 +279,25 @@
   /*************************************************************************/
 
 
-  FT_CALLBACK_DEF( FT_Error )
-  ftc_image_cache_init( FTC_Image_Cache  cache )
-  {
-    return ftc_glyph_cache_init( (FTC_GlyphCache)cache,
-                                 &ftc_image_set_class );
-  }
 
-
   FT_CALLBACK_TABLE_DEF
   const FTC_Cache_ClassRec  ftc_image_cache_class =
   {
-    sizeof ( FTC_GlyphCacheRec ),
-    (FTC_Cache_InitFunc)  ftc_image_cache_init,
-    (FTC_Cache_DoneFunc)  ftc_glyph_cache_done,
+    sizeof( FTC_CacheRec ),
+    (FTC_Cache_InitFunc)       ftc_cache_init,
+    (FTC_Cache_ClearFunc)      ftc_cache_clear,
+    (FTC_Cache_DoneFunc)       ftc_cache_done,
 
-    sizeof ( FTC_ImageNodeRec ),
-    (FTC_Node_InitFunc)   ftc_image_node_init,
-    (FTC_Node_WeightFunc) ftc_image_node_weight,
-    (FTC_Node_CompareFunc)ftc_image_node_compare,
-    (FTC_Node_DoneFunc)   ftc_image_node_done
+    sizeof( FTC_ImageFamilyRec ),
+    (FTC_Family_InitFunc)      ftc_image_family_init,
+    (FTC_Family_CompareFunc)   ftc_image_family_compare,
+    (FTC_Family_DoneFunc)      ftc_glyph_family_done,
+
+    sizeof( FTC_ImageNodeRec ),
+    (FTC_Node_InitFunc)        ftc_image_node_init,
+    (FTC_Node_WeightFunc)      ftc_image_node_weight,
+    (FTC_Node_CompareFunc)     ftc_glyph_node_compare,
+    (FTC_Node_DoneFunc)        ftc_image_node_done
   };
 
 
@@ -311,8 +304,8 @@
   /* documentation is in ftcimage.h */
 
   FT_EXPORT_DEF( FT_Error )
-  FTC_Image_Cache_New( FTC_Manager       manager,
-                       FTC_Image_Cache  *acache )
+  FTC_ImageCache_New( FTC_Manager      manager,
+                      FTC_ImageCache  *acache )
   {
     return FTC_Manager_Register_Cache(
              manager,
@@ -324,20 +317,20 @@
   /* documentation is in ftcimage.h */
 
   FT_EXPORT_DEF( FT_Error )
-  FTC_Image_Cache_Acquire( FTC_Image_Cache  cache,
-                           FTC_Image_Desc*  desc,
-                           FT_UInt          gindex,
-                           FT_Glyph        *aglyph,
-                           FTC_Node        *anode )
+  FTC_ImageCache_Lookup( FTC_ImageCache  cache,
+                         FTC_ImageDesc*  desc,
+                         FT_UInt         gindex,
+                         FT_Glyph       *aglyph,
+                         FTC_Node       *anode )
   {
-    FTC_ImageQueryRec  query;
+    FTC_ImageQueryRec  iquery;
     FTC_ImageNode      node;
     FT_Error           error;
 
 
-    /* some argument checks are delayed to ftc_glyph_cache_lookup() */
-    if ( !cache || !desc || !aglyph )
-      return FTC_Err_Invalid_Argument;
+    /* some argument checks are delayed to ftc_glyph_cache_lookup */
+    if ( aglyph )
+      *aglyph = NULL;
 
     *aglyph = NULL;
 
@@ -344,17 +337,17 @@
     if ( anode )
       *anode  = NULL;
 
-    query.glyph.gindex = gindex;
-    query.glyph.gset   = NULL;
-    query.desc         = *desc;
-    error = ftc_glyph_cache_lookup( FTC_GLYPH_CACHE( cache ),
-                                    &query.glyph,
-                                    (FTC_GlyphNode*)&node );
+    iquery.gquery.gindex = gindex;
+    iquery.desc          = *desc;
+
+    error = ftc_cache_lookup( FTC_CACHE(cache),
+                              FTC_QUERY(&iquery),
+                              (FTC_Node*) &node );
     if ( !error )
     {
       *aglyph = node->glyph;
 
-      if ( anode )
+      if (anode)
       {
         *anode = (FTC_Node)node;
         FTC_NODE(node)->ref_count++;
@@ -365,11 +358,14 @@
   }
 
 
-  FT_EXPORT_DEF( void )
-  FTC_Image_Cache_Release( FTC_Image_Cache  icache,
-                           FTC_Node         node )
+
+ /* backwards-compatibility functions */
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_Image_Cache_New( FTC_Manager       manager,
+                       FTC_Image_Cache  *acache )
   {
-    ftc_node_unref( node, FTC_CACHE( icache ) );
+    return FTC_ImageCache_New( manager, (FTC_ImageCache*)acache );
   }
 
 
@@ -379,7 +375,19 @@
                           FT_UInt          gindex,
                           FT_Glyph        *aglyph )
   {
-    return FTC_Image_Cache_Acquire( icache, desc, gindex, aglyph, NULL );
+    FTC_ImageDesc  desc0;
+
+    if ( !desc )
+      return FT_Err_Invalid_Argument;
+
+    desc0.font = desc->font;
+    desc0.type = (FT_UInt32) desc->image_type;
+
+    return FTC_ImageCache_Lookup( (FTC_ImageCache)icache,
+                                   &desc0,
+                                   gindex,
+                                   aglyph,
+                                   NULL );
   }
 
 
--- a/src/cache/ftcmanag.c
+++ b/src/cache/ftcmanag.c
@@ -22,7 +22,6 @@
 #include FT_CACHE_INTERNAL_LRU_H
 #include FT_INTERNAL_OBJECTS_H
 #include FT_INTERNAL_DEBUG_H
-#include FT_LIST_H
 #include FT_SIZES_H
 
 #include "ftcerror.h"
@@ -63,12 +62,11 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  ftc_face_node_init( FTC_FaceNode  node,
-                      FTC_FaceID    face_id,
-                      FT_LruList    list )
+  ftc_face_node_init( FTC_FaceNode node,
+                      FTC_FaceID   face_id,
+                      FTC_Manager  manager )
   {
-    FTC_Manager  manager = FTC_LRU_GET_MANAGER( list );
-    FT_Error     error;
+    FT_Error  error;
 
 
     error = manager->request_face( face_id,
@@ -97,10 +95,9 @@
 
   FT_CALLBACK_DEF( void )
   ftc_face_node_done( FTC_FaceNode  node,
-                      FT_LruList    list )
+                      FTC_Manager   manager )
   {
-    FTC_Manager  manager = FTC_LRU_GET_MANAGER( list );
-    FT_Face      face    = node->face;
+    FT_Face  face    = node->face;
 
 
     /* we must begin by removing all sizes for the target face */
@@ -130,6 +127,36 @@
   };
 
 
+  /* documentation is in ftcache.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_Manager_Lookup_Face( 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;
+
+    error = FT_LruList_Lookup( manager->faces_list,
+                               (FT_LruKey)face_id,
+                               (FT_LruNode*)&node );
+    if ( !error )
+      *aface = node->face;
+
+    return error;
+  }
+
+
+
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -242,9 +269,172 @@
   };
 
 
+
+  /* documentation is in ftcache.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_Manager_Lookup_Size( FTC_Manager  manager,
+                           FTC_Font     font,
+                           FT_Face     *aface,
+                           FT_Size     *asize )
+  {
+    FT_Error  error;
+
+
+    /* check for valid `manager' delayed to FTC_Manager_Lookup_Face() */
+    if ( aface )
+      *aface = 0;
+
+    if ( asize )
+      *asize = 0;
+
+    error = FTC_Manager_Lookup_Face( manager, font->face_id, aface );
+    if ( !error )
+    {
+      FTC_SizeQueryRec  query;
+      FTC_SizeNode      node;
+
+
+      query.face   = *aface;
+      query.width  = font->pix_width;
+      query.height = font->pix_height;
+
+      error = FT_LruList_Lookup( manager->sizes_list,
+                                 (FT_LruKey)&query,
+                                 (FT_LruNode*)&node );
+      if ( !error )
+      {
+        /* select the size as the current one for this face */
+        FT_Activate_Size( node->size );
+
+        if ( asize )
+          *asize = node->size;
+      }
+    }
+
+    return error;
+  }
+
+
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
+  /*****                    SET TABLE MANAGEMENT                       *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  static void
+  ftc_family_table_init( FTC_FamilyTable  table )
+  {
+    table->count   = 0;
+    table->size    = 0;
+    table->entries = NULL;
+    table->free    = FTC_FAMILY_ENTRY_NONE;
+  }
+
+
+  static void
+  ftc_family_table_done( FTC_FamilyTable  table,
+                         FT_Memory        memory )
+  {
+    FREE( table->entries );
+    table->free  = 0;
+    table->count = 0;
+    table->size  = 0;
+  }
+
+
+  FT_LOCAL_DEF FT_Error
+  ftc_family_table_alloc( FTC_FamilyTable   table,
+                          FT_Memory         memory,
+                          FTC_FamilyEntry  *aentry )
+  {
+    FTC_FamilyEntry  entry;
+    FT_Error         error = 0;
+
+   /* re-allocate table size when needed */
+    if ( table->free == FTC_FAMILY_ENTRY_NONE && table->count >= table->size )
+    {
+      FT_UInt  old_size = table->size;
+      FT_UInt  new_size, index;
+
+      if ( old_size == 0 )
+        new_size = 8;
+      else
+      {
+        new_size = old_size*2;
+
+        /* check for (unlikely) overflow */
+        if ( new_size < old_size )
+          new_size = 65534;
+      }
+
+      if ( REALLOC_ARRAY( table->entries, old_size, new_size, FTC_FamilyEntryRec ) )
+        return error;
+
+      table->size = new_size;
+
+      entry       = table->entries + old_size;
+      table->free = old_size;
+
+      for ( index = old_size; index+1 < new_size; index++, entry++ )
+      {
+        entry->link  = index+1;
+        entry->index = index;
+      }
+
+      entry->link  = FTC_FAMILY_ENTRY_NONE;
+      entry->index = index;
+    }
+
+    if ( table->free != FTC_FAMILY_ENTRY_NONE )
+    {
+      entry       = table->entries + table->free;
+      table->free = entry->link;
+    }
+    else if ( table->count < table->size )
+    {
+      entry = table->entries + table->count++;
+    }
+    else
+    {
+      FT_ERROR(( "FreeType.cache.alloc_set: internal bug !!" ));
+      return FT_Err_Invalid_Argument;
+    }
+
+    entry->link = FTC_FAMILY_ENTRY_NONE;
+    table->count++;
+
+    *aentry = entry;
+    return error;
+  }
+
+
+  FT_LOCAL_DEF void
+  ftc_family_table_free( FTC_FamilyTable  table,
+                         FT_UInt          index )
+  {
+    /* simply add it to the linked list of free entries */
+    if ( index < table->count )
+    {
+      FTC_FamilyEntry  entry = table->entries + index;
+
+      if ( entry->link != FTC_FAMILY_ENTRY_NONE )
+        FT_ERROR(( "FreeType.cache.set_free: internal bug !!\n" ));
+      else
+      {
+        entry->link = table->free;
+        table->free = entry->index;
+        table->count--;
+      }
+    }
+  }
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
   /*****                    CACHE MANAGER ROUTINES                     *****/
   /*****                                                               *****/
   /*************************************************************************/
@@ -307,6 +497,8 @@
     manager->request_face = requester;
     manager->request_data = req_data;
 
+    ftc_family_table_init( &manager->families );
+
     *amanager = manager;
 
   Exit:
@@ -348,7 +540,10 @@
         manager->caches[index] = 0;
       }
     }
-    
+
+    /* discard families table */
+    ftc_family_table_done( &manager->families, memory );
+
     /* discard faces and sizes */
     FT_LruList_Destroy( manager->faces_list );
     manager->faces_list = 0;
@@ -374,251 +569,10 @@
   }
 
 
-  /* documentation is in ftcache.h */
 
-  FT_EXPORT_DEF( FT_Error )
-  FTC_Manager_Lookup_Face( 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;
-
-    error = FT_LruList_Lookup( manager->faces_list,
-                               (FT_LruKey)face_id,
-                               (FT_LruNode*)&node );
-    if ( !error )
-      *aface = node->face;
-    
-    return error;
-  }
-
-
-  /* documentation is in ftcache.h */
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_Manager_Lookup_Size( FTC_Manager  manager,
-                           FTC_Font     font,
-                           FT_Face     *aface,
-                           FT_Size     *asize )
-  {
-    FT_Error  error;
-
-
-    /* check for valid `manager' delayed to FTC_Manager_Lookup_Face() */
-    if ( aface )
-      *aface = 0;
-
-    if ( asize )
-      *asize = 0;
-
-    error = FTC_Manager_Lookup_Face( manager, font->face_id, aface );
-    if ( !error )
-    {
-      FTC_SizeQueryRec  query;
-      FTC_SizeNode      node;
-
-
-      query.face   = *aface;
-      query.width  = font->pix_width;
-      query.height = font->pix_height;
-
-      error = FT_LruList_Lookup( manager->sizes_list,
-                                 (FT_LruKey)&query,
-                                 (FT_LruNode*)&node );
-      if ( !error )
-      {
-        /* select the size as the current one for this face */
-        FT_Activate_Size( node->size );
-
-        if ( asize )
-          *asize = node->size;
-      }
-    }
-
-    return error;
-  }
-
-
-  /* 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_Node  first = manager->nodes_list;
-
-
-    if ( first )
-    {
-      node->mru_prev = first->mru_prev;
-      node->mru_next = first;
-
-      first->mru_prev->mru_next = node;
-      first->mru_prev           = node;
-    }
-    else
-    {
-      node->mru_next = node;
-      node->mru_prev = node;
-    }
-
-    manager->nodes_list = 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_Node  prev  = node->mru_prev;
-    FTC_Node  next  = node->mru_next;
-    FTC_Node  first = manager->nodes_list;
-
-
-    prev->mru_next = next;
-    next->mru_prev = prev;
-
-    if ( node->mru_next == first )
-    {
-      /* this is the last node in the list; update its head pointer */
-      if ( node == first )
-        manager->nodes_list = NULL;
-      else
-        first->mru_prev = prev;
-    }
-
-    node->mru_next = NULL;
-    node->mru_prev = NULL;
-    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_Node  first = manager->nodes_list;
-
-
-    if ( node != first )
-    {
-      ftc_node_mru_unlink( node, manager );
-      ftc_node_mru_link( node, manager );
-    }
-  }
-
-
-  /* remove a node from its cache's hash table */
-  static void
-  ftc_node_hash_unlink( FTC_Node   node,
-                        FTC_Cache  cache )
-  {
-    FTC_Node  *pnode = cache->buckets + ( node->hash % cache->size );
-
-
-    for (;;)
-    {
-      if ( *pnode == NULL )
-      {
-        FT_ERROR(( "FreeType.cache.hash_unlink: unknown node!\n" ));
-        return;
-      }
-
-      if ( *pnode == node )
-      {
-        *pnode     = node->link;
-        node->link = NULL;
-
-        cache->nodes--;
-        return;
-      }
-
-      pnode = &(*pnode)->link;
-    }
-  }
-
-
-  /* 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 = cache->buckets + ( node->hash % cache->size );
-
-
-    node->link = *pnode;
-    *pnode     = node;
-
-    cache->nodes++;
-  }
-
-
-  /* remove a node from the cache manager */
-  static void
-  ftc_node_destroy( FTC_Node     node,
-                    FTC_Manager  manager )
-  {
-    FT_Memory        memory  = manager->library->memory;
-    FTC_Cache        cache;
-    FTC_Cache_Class  clazz;
-
-
 #ifdef FT_DEBUG_ERROR
-    /* find node's cache */
-    if ( node->cache_index >= FTC_MAX_CACHES )
-    {
-      FT_ERROR(( "FreeType.cache.node_destroy: invalid node handle\n" ));
-      return;
-    }
-#endif
-
-    cache = manager->caches[node->cache_index];
-
-#ifdef FT_DEBUG_ERROR
-    if ( cache == NULL )
-    {
-      FT_ERROR(( "FreeType.cache.node_destroy: invalid node handle\n" ));
-      return;
-    }
-#endif
-
-    clazz = cache->clazz;
-
-    manager->cur_weight -= 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 */
-
-    if ( clazz->node_done )
-      clazz->node_done( node, cache );
-
-    FREE( node );
-
-    /* check, just in case of general corruption :-) */
-    if ( manager->num_nodes <= 0 )
-      FT_ERROR(( "FTC_Manager_Compress: Invalid cache node count! = %d\n",
-                  manager->num_nodes ));
-  }
-
-
-  FT_EXPORT_DEF( void )
+  FT_EXPORT_DEF(void)
   FTC_Manager_Check( FTC_Manager  manager )
   {
     FTC_Node  node, first;
@@ -636,14 +590,23 @@
 
       do
       {
-        FTC_Cache  cache = manager->caches[node->cache_index];
-        
+        FTC_FamilyEntry  entry = manager->families.entries + node->fam_index;
+        FTC_Cache     cache;
 
-        weight += cache->clazz->node_weight( node, cache );
-        node    = node->mru_next;
+        if ( (FT_UInt)node->fam_index >= manager->families.count ||
+             entry->link              != FTC_FAMILY_ENTRY_NONE  )
+          FT_ERROR(( "FTC_Manager_Compress: invalid node (family index = %ld\n",
+                     node->fam_index ));
+        else
+        {
+          cache   = entry->cache;
+          weight += cache->clazz->node_weight( node, cache );
+        }
 
-      } while ( node != first );
-      
+        node = node->mru_next;
+      }
+      while (node != first);
+
       if ( weight != manager->cur_weight )
         FT_ERROR((
           "FTC_Manager_Compress: invalid weight %ld instead of %ld\n",
@@ -654,16 +617,16 @@
     if ( first )
     {
       FT_UFast  count = 0;
-      
 
+
       node = first;
       do
       {
         count++;
         node = node->mru_next;
+      }
+      while (node != first);
 
-      } while ( node != first );
-      
       if ( count != manager->num_nodes )
         FT_ERROR((
           "FTC_Manager_Compress: invalid cache node count %d instead of %d\n",
@@ -670,6 +633,7 @@
           manager->num_nodes, count ));
     }
   }
+#endif /* FT_DEBUG_ERROR */
 
 
   /* `Compress' the manager's data, i.e., get rid of old cache nodes */
@@ -689,7 +653,7 @@
 
     first = manager->nodes_list;
 
-#if 0
+#ifdef FT_DEBUG_ERROR
     FTC_Manager_Check( manager );
 
     FT_ERROR(( "compressing, weight = %ld, max = %ld, nodes = %d\n",
@@ -782,296 +746,20 @@
   }
 
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                    ABSTRACT CACHE CLASS                       *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
 
-#define FTC_PRIMES_MIN  7
-#define FTC_PRIMES_MAX  13845163
 
-  static const FT_UInt  ftc_primes[] =
-  {
-    7,
-    11,
-    19,
-    37,
-    73,
-    109,
-    163,
-    251,
-    367,
-    557,
-    823,
-    1237,
-    1861,
-    2777,
-    4177,
-    6247,
-    9371,
-    14057,
-    21089,
-    31627,
-    47431,
-    71143,
-    106721,
-    160073,
-    240101,
-    360163,
-    540217,
-    810343,
-    1215497,
-    1823231,
-    2734867,
-    4102283,
-    6153409,
-    9230113,
-    13845163,
-  };
 
 
-  static FT_UFast
-  ftc_prime_closest( FT_UFast  num )
-  {
-    FT_UInt  i;
 
-
-    for ( i = 0; i < sizeof ( ftc_primes ) / sizeof ( ftc_primes[0] ); i++ )
-      if ( ftc_primes[i] > num )
-        return ftc_primes[i];
-
-    return FTC_PRIMES_MAX;
-  }
-
-
-  FT_EXPORT_DEF( void )
-  ftc_cache_resize( FTC_Cache  cache )
+  FT_EXPORT_DEF(void)
+  FTC_Node_Unref( FTC_Node     node,
+                  FTC_Manager  manager )
   {
-    FT_UFast  new_size;
-
-
-    new_size = ftc_prime_closest( cache->nodes );
-    if ( new_size != cache->size )
+    if ( node && (FT_UInt)node->fam_index < manager->families.count &&
+         manager->families.entries[node->fam_index].cache )
     {
-      FT_Memory  memory = cache->memory;
-      FT_Error   error;
-      FTC_Node*  new_buckets ;
-      FT_ULong   i;
-
-
-      if ( ALLOC_ARRAY( new_buckets, new_size, FTC_Node ) )
-        return;
-
-      for ( i = 0; i < cache->size; i++ )
-      {
-        FTC_Node   node, next, *pnode;
-        FT_UFast   hash;
-
-
-        node = cache->buckets[i];
-        while ( node )
-        {
-          next  = node->link;
-          hash  = node->hash % new_size;
-          pnode = new_buckets + hash;
-
-          node->link = pnode[0];
-          pnode[0]   = node;
-
-          node = next;
-        }
-      }
-
-      if ( cache->buckets )
-        FREE( cache->buckets );
-
-      cache->buckets = new_buckets;
-      cache->size    = new_size;
-    }
-  }
-
-
-  FT_EXPORT_DEF( FT_Error )
-  ftc_cache_init( FTC_Cache  cache )
-  {
-    FT_Memory  memory = cache->memory;
-    FT_Error   error;
-    
-
-    cache->nodes = 0;
-    cache->size  = FTC_PRIMES_MIN;
-    
-    if ( ALLOC_ARRAY( cache->buckets, cache->size, FTC_Node ) )
-      goto Exit;
-      
-  Exit:
-    return error;
-  }
-
-
-  FT_EXPORT_DEF( void )
-  ftc_cache_done( FTC_Cache  cache )
-  {
-    if ( cache )
-    {
-      FT_Memory        memory  = cache->memory;
-      FTC_Cache_Class  clazz   = cache->clazz;
-      FTC_Manager      manager = cache->manager;
-      FT_UFast         i;
-
-
-      for ( i = 0; i < cache->size; 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 -= clazz->node_weight( node, cache );
-
-          if ( clazz->node_done )
-            clazz->node_done( node, cache );
-
-          FREE( node );
-          node = next;
-        }
-        cache->buckets[i] = NULL;
-      }
-
-      FREE( cache->buckets );
-
-      cache->nodes = 0;
-      cache->size  = 0;
-    }
-  }
-
-
-  /* Look up a node in "top" of its cache's hash table. */
-  /* If not found, create a new node.                   */
-  /*                                                    */
-  FT_EXPORT_DEF( FT_Error )
-  ftc_cache_lookup_node( FTC_Cache   cache,
-                         FT_UFast    key_hash,
-                         FT_Pointer  key,
-                         FTC_Node   *anode )
-  {
-    FT_Error   error  = 0;
-    FTC_Node   result = NULL;
-    FTC_Node*  bucket = cache->buckets + ( key_hash % cache->size );
-
-
-    if ( *bucket )
-    {
-      FTC_Node*             pnode   = bucket;
-      FTC_Node_CompareFunc  compare = cache->clazz->node_compare;
-
-
-      for (;;)
-      {
-        FTC_Node  node;
-
-
-        node = *pnode;
-        if ( node == NULL )
-          break;
-
-        if ( compare( node, key, cache ) )
-        {
-          /* move to head of bucket list */
-          if ( pnode != bucket )
-          {
-            *pnode     = node->link;
-            node->link = *bucket;
-            *bucket    = node;
-          }
-          
-          /* move to head of MRU list */
-          if ( node != cache->manager->nodes_list )
-            ftc_node_mru_up( node, cache->manager );
-
-          result = node;
-          goto Exit;
-        }
-
-        pnode = &(*pnode)->link;
-      }
-    }
-
-    /* didn't find a node, create a new one */
-    {
-      FTC_Cache_Class  clazz   = cache->clazz;
-      FTC_Manager      manager = cache->manager;
-      FT_Memory        memory  = cache->memory;
-      FTC_Node         node;
-
-
-      if ( ALLOC( node, clazz->node_size ) )
-        goto Exit;
-
-      /* node initializer must set 'hash' field */
-
-      node->cache_index = cache->cache_index;
-      node->ref_count   = 0;
-
-      error = clazz->node_init( node, key, cache );
-      if ( error )
-      {
-        FREE( node );
-        goto Exit;
-      }
-
-      ftc_node_hash_link( node, cache );
-      ftc_node_mru_link( node, cache->manager );
-
-      cache->manager->cur_weight += clazz->node_weight( node, cache );
-
-      /* now try to compress the node pool when necessary */
-      if ( manager->cur_weight >= manager->max_weight )
-      {
-        node->ref_count++;
-        FTC_Manager_Compress( manager );
-        node->ref_count--;
-      }
-
-      /* try to resize the hash table when appropriate */
-      if ( FTC_CACHE_RESIZE_TEST( cache ) )
-        ftc_cache_resize( cache );
-
-      result = node;
-    }
-
-  Exit:
-   *anode = result;
-    return error;
-  }
-
-
-  /* maybe the next two functions will disappear eventually */
-
-  FT_EXPORT_DEF( void )
-  ftc_node_ref( FTC_Node   node,
-                FTC_Cache  cache )
-  {
-    if ( node && cache && (FT_UInt)node->cache_index == cache->cache_index )
-      node->ref_count++;
-  }
-
-
-  FT_EXPORT_DEF( void )
-  ftc_node_unref( FTC_Node   node,
-                  FTC_Cache  cache )
-  {
-    if ( node && cache && (FT_UInt)node->cache_index == cache->cache_index )
       node->ref_count--;
+    }
   }
 
 
--- a/src/cache/ftcsbits.c
+++ b/src/cache/ftcsbits.c
@@ -19,7 +19,7 @@
 #include <ft2build.h>
 #include FT_CACHE_H
 #include FT_CACHE_SMALL_BITMAPS_H
-#include FT_CACHE_INTERNAL_CHUNK_H
+#include FT_CACHE_INTERNAL_GLYPH_H
 #include FT_INTERNAL_OBJECTS_H
 #include FT_INTERNAL_DEBUG_H
 #include FT_ERRORS_H
@@ -32,30 +32,45 @@
 #define FTC_SBIT_ITEMS_PER_NODE  16
 
 
- /* handle to sbit set */
-  typedef struct FTC_SBitSetRec_*  FTC_SBitSet;
+  typedef struct FTC_SBitNodeRec_*    FTC_SBitNode;
 
- /* sbit set structure */
-  typedef struct  FTC_SBitSetRec_
+  typedef struct FTC_SBitNodeRec_
   {
-    FTC_ChunkSetRec  cset;
-    FTC_Image_Desc   desc;
+    FTC_GlyphNodeRec   gnode;
+    FTC_SBitRec        sbits[ FTC_SBIT_ITEMS_PER_NODE ];
 
-  } FTC_SBitSetRec;
+  } FTC_SBitNodeRec;
 
+#define  FTC_SBIT_NODE(x)   ((FTC_SBitNode)(x))
 
-#define FTC_SBIT_SET( x )         ( (FTC_SBitSet)(x) )
-#define FTC_SBIT_SET_MEMORY( x )  FTC_CHUNK_SET_MEMORY( &(x)->cset )
 
 
   typedef struct  FTC_SBitQueryRec_
   {
-    FTC_ChunkQueryRec  chunk;
-    FTC_Image_Desc     desc;
+    FTC_GlyphQueryRec  gquery;
+    FTC_ImageDesc      desc;
 
   } FTC_SBitQueryRec, *FTC_SBitQuery;
 
+#define  FTC_SBIT_QUERY(x)  ((FTC_SBitQuery)(x))
 
+
+
+  typedef struct FTC_SBitFamilyRec_*  FTC_SBitFamily;
+
+ /* sbit family structure */
+  typedef struct  FTC_SBitFamilyRec_
+  {
+    FTC_GlyphFamilyRec  gfam;
+    FTC_ImageDesc       desc;
+
+  } FTC_SBitFamilyRec;
+  
+#define FTC_SBIT_FAMILY( x )         ( (FTC_SBitFamily)(x) )
+#define FTC_SBIT_FAMILY_MEMORY( x )  FTC_GLYPH_FAMILY_MEMORY( &(x)->cset )
+
+
+
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -65,31 +80,10 @@
   /*************************************************************************/
 
 
-  FT_CALLBACK_DEF( void )
-  ftc_sbit_node_done( FTC_ChunkNode  cnode )
-  {
-    FTC_ChunkSet  cset   = cnode->cset;
-    FT_Memory     memory = cset->ccache->cache.memory;
-    FT_UInt       count  = cnode->item_count;
-    FTC_SBit      sbit   = (FTC_SBit) cnode->items;
-
-
-    if ( sbit )
-    {
-      for ( ; count > 0; sbit++, count-- )
-        FREE( sbit->buffer );
-
-      FREE( cnode->items );
-    }
-
-    ftc_chunk_node_done( cnode );
-  }
-
-
   static FT_Error
-  ftc_sbit_set_bitmap( FTC_SBit    sbit,
-                       FT_Bitmap*  bitmap,
-                       FT_Memory   memory )
+  ftc_sbit_copy_bitmap( FTC_SBit    sbit,
+                        FT_Bitmap*  bitmap,
+                        FT_Memory   memory )
   {
     FT_Error  error;
     FT_Int    pitch = bitmap->pitch;
@@ -108,49 +102,69 @@
   }
 
 
+
+  FT_CALLBACK_DEF( void )
+  ftc_sbit_node_done( FTC_SBitNode  snode,
+                      FTC_Cache     cache )
+  {
+    FTC_SBit   sbit  = snode->sbits;
+    FT_UInt    count = FTC_GLYPH_NODE(snode)->item_count;
+    FT_Memory  memory = cache->memory;
+
+
+    for ( ; count > 0; sbit++, count-- )
+      FREE( sbit->buffer );
+
+    ftc_glyph_node_done( FTC_GLYPH_NODE(snode), cache );
+  }
+
+
   static FT_Error
-  ftc_sbit_node_load( FTC_ChunkNode  cnode,
-                      FT_UInt        gindex,
-                      FT_ULong      *asize )
+  ftc_sbit_node_load( FTC_SBitNode  snode,
+                      FTC_Manager   manager,
+                      FT_UInt       gindex,
+                      FT_ULong     *asize )
   {
     FT_Error       error;
-    FTC_ChunkSet   cset    = cnode->cset;
-    FTC_SBitSet    sbitset = FTC_SBIT_SET(cset);
-    FT_Memory      memory  = FTC_SBIT_SET_MEMORY(sbitset);
+    FTC_GlyphNode  gnode = FTC_GLYPH_NODE(snode);
+    FTC_GlyphFamily   gfam;
+    FTC_SBitFamily    sfam;
+    FT_Memory      memory;
     FT_Face        face;
     FT_Size        size;
-
     FTC_SBit       sbit;
 
-
-    if ( gindex <  (FT_UInt)cnode->item_start                     ||
-         gindex >= (FT_UInt)cnode->item_start + cnode->item_count )
+    if ( gindex <  (FT_UInt)gnode->item_start                     ||
+         gindex >= (FT_UInt)gnode->item_start + gnode->item_count )
     {
       FT_ERROR(( "FreeType.cache.sbit_load: invalid glyph index" ));
       return FTC_Err_Invalid_Argument;
     }
 
-    sbit = (FTC_SBit)cnode->items + ( gindex - cnode->item_start );
+    gfam   = FTC_GLYPH_FAMILY( manager->families.entries[ gnode->node.fam_index ].family );
+    sfam   = FTC_SBIT_FAMILY(gfam);
+    memory = manager->library->memory;
 
-    error = FTC_Manager_Lookup_Size( cset->ccache->cache.manager,
-                                     &sbitset->desc.font,
+    sbit = snode->sbits + (gindex - gnode->item_start);
+
+    error = FTC_Manager_Lookup_Size( manager, &sfam->desc.font,
                                      &face, &size );
     if ( !error )
     {
       FT_UInt   load_flags  = FT_LOAD_DEFAULT;
-      FT_UInt   image_type  = sbitset->desc.image_type;
+      FT_UInt   type  = sfam->desc.type;
 
 
       /* determine load flags, depending on the font description's */
       /* image type                                                */
 
-      if ( FTC_IMAGE_FORMAT( image_type ) == ftc_image_format_bitmap )
+      if ( FTC_IMAGE_FORMAT( type ) == ftc_image_format_bitmap )
       {
-        if ( image_type & ftc_image_flag_monochrome )
+        if ( type & ftc_image_flag_monochrome )
           load_flags |= FT_LOAD_MONOCHROME;
 
         /* disable embedded bitmaps loading if necessary */
-        if ( image_type & ftc_image_flag_no_sbits )
+        if ( type & ftc_image_flag_no_sbits )
           load_flags |= FT_LOAD_NO_BITMAP;
       }
       else
@@ -165,10 +179,10 @@
       /* always render glyphs to bitmaps */
       load_flags |= FT_LOAD_RENDER;
 
-      if ( image_type & ftc_image_flag_unhinted )
+      if ( type & ftc_image_flag_unhinted )
         load_flags |= FT_LOAD_NO_HINTING;
 
-      if ( image_type & ftc_image_flag_autohinted )
+      if ( type & ftc_image_flag_autohinted )
         load_flags |= FT_LOAD_FORCE_AUTOHINT;
 
       /* by default, indicates a `missing' glyph */
@@ -222,13 +236,13 @@
           else
           {
             /* copy the bitmap into a new buffer -- ignore error */
-            error = ftc_sbit_set_bitmap( sbit, bitmap, memory );
+            error = ftc_sbit_copy_bitmap( sbit, bitmap, memory );
           }
 
           /* now, compute size */
           if ( asize )
-            *asize = ABS( sbit->pitch ) * sbit->height;
-          
+            *asize = ABS(sbit->pitch) * sbit->height;
+
         }  /* glyph dimensions ok */
 
       } /* glyph loading successful */
@@ -251,45 +265,39 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  ftc_sbit_node_init( FTC_ChunkNode   cnode,
-                      FTC_ChunkQuery  query )
+  ftc_sbit_node_init( FTC_SBitNode    snode,
+                      FTC_GlyphQuery  gquery,
+                      FTC_Cache       cache )
   {
     FT_Error  error;
 
+    ftc_glyph_node_init( FTC_GLYPH_NODE(snode),
+                         gquery->gindex,
+                         FTC_GLYPH_FAMILY(gquery->query.family) );
 
-    error = ftc_chunk_node_init( cnode,
-                                 query->cset,
-                                 query->gindex,
-                                 TRUE );
-    if ( !error )
-    {
-      error = ftc_sbit_node_load( cnode, query->gindex, NULL );
+    error = ftc_sbit_node_load( snode, cache->manager, gquery->gindex, NULL );
+    if ( error )
+      ftc_glyph_node_done( FTC_GLYPH_NODE(snode), cache );
 
-      if ( error )
-        ftc_chunk_node_done( cnode );
-    }
-
     return error;
   }
 
 
-  /* this function is important because it is both part of */
-  /* an FTC_ChunkSet_Class and an FTC_CacheNode_Class      */
-  /*                                                       */
   FT_CALLBACK_DEF( FT_ULong )
-  ftc_sbit_node_weight( FTC_ChunkNode  cnode )
+  ftc_sbit_node_weight( FTC_SBitNode  snode )
   {
-    FT_ULong  size;
-    FT_UInt   count = cnode->item_count;
-    FT_Int    pitch;
-    FTC_SBit  sbit  = (FTC_SBit) cnode->items;
+    FTC_GlyphNode  gnode = FTC_GLYPH_NODE(snode);
+    FT_UInt        count = gnode->item_count;
+    FTC_SBit       sbit  = snode->sbits;
+    FT_Int         pitch;
+    FT_ULong       size;
 
 
     /* the node itself */
-    size = sizeof ( *cnode );
+    size  = sizeof ( *snode );
 
     /* the sbit records */
-    size += cnode->item_count * sizeof ( FTC_SBitRec );
+    size += FTC_GLYPH_NODE(snode)->item_count * sizeof ( FTC_SBitRec );
 
     for ( ; count > 0; count--, sbit++ )
     {
@@ -309,30 +317,26 @@
 
 
   FT_CALLBACK_DEF( FT_Bool )
-  ftc_sbit_node_compare( FTC_ChunkNode  cnode,
-                         FTC_SBitQuery  query,
+  ftc_sbit_node_compare( FTC_SBitNode   snode,
+                         FTC_SBitQuery  squery,
                          FTC_Cache      cache )
   {
-    FTC_ChunkQuery  creq  = &query->chunk;
-    FT_UInt         gindex = query->chunk.gindex;
-    FT_UInt         offset = (FT_UInt)(gindex - cnode->item_start);
+    FTC_GlyphQuery  gquery = FTC_GLYPH_QUERY(squery);
+    FTC_GlyphNode   gnode  = FTC_GLYPH_NODE(snode);
     FT_Bool         result;
 
-
-    result = FT_BOOL( offset < (FT_UInt)cnode->item_count &&
-                      creq->cset == cnode->cset );
+    result = ftc_glyph_node_compare( gnode, gquery );
     if ( result )
     {
       /* check if we need to load the glyph bitmap now */
-      FTC_SBit  sbit = (FTC_SBit)cnode->items + offset;
-      
+      FT_UInt   gindex = gquery->gindex;
+      FTC_SBit  sbit   = snode->sbits + (gindex - gnode->item_start);
 
       if ( sbit->buffer == NULL && sbit->width != 255 )
       {
         FT_ULong  size;
 
-
-        ftc_sbit_node_load( cnode, gindex, &size );
+        ftc_sbit_node_load( snode, cache->manager, gindex, &size );
         cache->manager->cur_weight += size;
       }
     }
@@ -344,7 +348,7 @@
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
-  /*****                     SBIT CHUNK SETS                           *****/
+  /*****                     SBITS FAMILIES                            *****/
   /*****                                                               *****/
   /*************************************************************************/
   /*************************************************************************/
@@ -351,34 +355,28 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  ftc_sbit_set_init( FTC_SBitSet    sset,
-                     FTC_SBitQuery  query,
-                     FT_LruList     lru )
+  ftc_sbit_family_init( FTC_SBitFamily  sfam,
+                        FTC_SBitQuery   squery,
+                        FTC_Cache       cache )
   {
-    FTC_ChunkCache  ccache  = lru->user_data;
-    FTC_Manager     manager = ccache->cache.manager;
-    FT_Error        error;
-    FT_Face         face;
+    FTC_Manager  manager = cache->manager;
+    FT_Error     error;
+    FT_Face      face;
 
+    sfam->desc = squery->desc;
 
-    sset->desc = query->desc;
-
     /* we need to compute "cquery.item_total" now */
     error = FTC_Manager_Lookup_Face( manager,
-                                     query->desc.font.face_id,
+                                     squery->desc.font.face_id,
                                      &face );
     if ( !error )
     {
-      ftc_chunk_set_init( FTC_CHUNK_SET( sset ),
-                          sizeof ( FTC_SBitRec ),
-                          FTC_SBIT_ITEMS_PER_NODE,
-                          face->num_glyphs,
-                          FTC_CHUNK_CACHE( lru->user_data ) );
-
-      /* now compute hash from description -- this is _very_ important */
-      /* for good performance                                          */
-      sset->cset.hash   = FTC_IMAGE_DESC_HASH( &sset->desc );
-      query->chunk.cset = &sset->cset;
+      error = ftc_glyph_family_init( FTC_GLYPH_FAMILY(sfam),
+                                     FTC_IMAGE_DESC_HASH( &sfam->desc ),
+                                     FTC_SBIT_ITEMS_PER_NODE,
+                                     face->num_glyphs,
+                                     FTC_GLYPH_QUERY(squery),
+                                     cache );
     }
 
     return error;
@@ -386,38 +384,24 @@
 
 
   FT_CALLBACK_DEF( FT_Bool )
-  ftc_sbit_set_compare( FTC_SBitSet    sset,
-                        FTC_SBitQuery  query )
+  ftc_sbit_family_compare( FTC_SBitFamily    sfam,
+                        FTC_SBitQuery  squery )
   {
     FT_Bool  result;
 
 
     /* we need to set the "cquery.cset" field or our query for */
-    /* faster glyph comparisons in ftc_sbit_node_compare()     */
-    /*                                                         */
-    result = FT_BOOL( FTC_IMAGE_DESC_COMPARE( &sset->desc, &query->desc ) );
+    /* faster glyph comparisons in ftc_sbit_node_compare..         */
+    /*                                                             */
+    result = FT_BOOL( FTC_IMAGE_DESC_COMPARE( &sfam->desc, &squery->desc ) );
     if ( result )
-      query->chunk.cset = &sset->cset;
+      FTC_GLYPH_FAMILY_FOUND(sfam,squery);
 
     return result;
   }
 
 
-  FT_CALLBACK_TABLE_DEF
-  const FT_LruList_ClassRec  ftc_sbit_set_class =
-  {
-    sizeof ( FT_LruListRec ),
-    (FT_LruList_InitFunc)   NULL,
-    (FT_LruList_DoneFunc)   NULL,
 
-    sizeof ( FTC_SBitSetRec ),
-    (FT_LruNode_InitFunc)   ftc_sbit_set_init,
-    (FT_LruNode_DoneFunc)   ftc_chunk_set_done,
-    (FT_LruNode_FlushFunc)  NULL,
-    (FT_LruNode_CompareFunc)ftc_sbit_set_compare,
-  };
-
-
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -427,26 +411,25 @@
   /*************************************************************************/
 
 
-  FT_CALLBACK_DEF( FT_Error )
-  ftc_sbit_cache_init( FTC_SBit_Cache  scache )
-  {
-    return ftc_chunk_cache_init( FTC_CHUNK_CACHE( scache ),
-                                 &ftc_sbit_set_class );
-  }
 
-
   FT_CALLBACK_TABLE_DEF
   const FTC_Cache_ClassRec  ftc_sbit_cache_class =
   {
-    sizeof ( FTC_ChunkCacheRec ),
-    (FTC_Cache_InitFunc)  ftc_sbit_cache_init,
-    (FTC_Cache_DoneFunc)  ftc_chunk_cache_done,
+    sizeof( FTC_CacheRec ),
+    (FTC_Cache_InitFunc)  ftc_cache_init,
+    (FTC_Cache_ClearFunc) ftc_cache_clear,
+    (FTC_Cache_DoneFunc)  ftc_cache_done,
 
-    sizeof ( FTC_ChunkNodeRec ),
-    (FTC_Node_InitFunc)   ftc_sbit_node_init,
-    (FTC_Node_WeightFunc) ftc_sbit_node_weight,
-    (FTC_Node_CompareFunc)ftc_sbit_node_compare,
-    (FTC_Node_DoneFunc)   ftc_sbit_node_done
+    sizeof( FTC_SBitFamilyRec ),
+    (FTC_Family_InitFunc)    ftc_sbit_family_init,
+    (FTC_Family_CompareFunc) ftc_sbit_family_compare,
+    (FTC_Family_DoneFunc)    ftc_glyph_family_done,
+
+    sizeof( FTC_SBitNodeRec ),
+    (FTC_Node_InitFunc)     ftc_sbit_node_init,
+    (FTC_Node_WeightFunc)   ftc_sbit_node_weight,
+    (FTC_Node_CompareFunc)  ftc_sbit_node_compare,
+    (FTC_Node_DoneFunc)     ftc_sbit_node_done
   };
 
 
@@ -453,8 +436,8 @@
   /* documentation is in ftcsbits.h */
 
   FT_EXPORT_DEF( FT_Error )
-  FTC_SBit_Cache_New( FTC_Manager      manager,
-                      FTC_SBit_Cache  *acache )
+  FTC_SBitCache_New( FTC_Manager     manager,
+                     FTC_SBitCache  *acache )
   {
     return FTC_Manager_Register_Cache( manager,
                                        &ftc_sbit_cache_class,
@@ -465,34 +448,77 @@
   /* documentation is in ftcsbits.h */
 
   FT_EXPORT_DEF( FT_Error )
-  FTC_SBit_Cache_Lookup( FTC_SBit_Cache   cache,
-                         FTC_Image_Desc*  desc,
-                         FT_UInt          gindex,
-                         FTC_SBit        *ansbit )
+  FTC_SBitCache_Lookup( FTC_SBitCache   cache,
+                        FTC_ImageDesc*  desc,
+                        FT_UInt         gindex,
+                        FTC_SBit       *ansbit,
+                        FTC_Node       *anode )
   {
     FT_Error          error;
-    FTC_ChunkCache    ccache = (FTC_ChunkCache) cache;
-    FTC_ChunkNode     node;
-    FTC_SBitQueryRec  query;
+    FTC_SBitQueryRec  squery;
+    FTC_SBitNode      node;
 
-
-    /* argument checks delayed to FTC_Chunk_Cache_Lookup */
+    /* argument checks delayed to ftc_cache_lookup */
     if ( !ansbit )
       return FTC_Err_Invalid_Argument;
 
     *ansbit = NULL;
 
-    query.chunk.gindex = gindex;
-    query.chunk.cset   = NULL;
-    query.desc         = *desc;
-    
-    error = ftc_chunk_cache_lookup( ccache, &query.chunk, &node );
+    if ( anode )
+      *anode = NULL;
+
+    squery.gquery.gindex = gindex;
+    squery.desc          = *desc;
+
+    error = ftc_cache_lookup( FTC_CACHE(cache),
+                              FTC_QUERY(&squery),
+                              (FTC_Node*) &node );
     if ( !error )
     {
-      *ansbit = (FTC_SBit)node->items + ( gindex - node->item_start );
+      *ansbit = node->sbits + (gindex - FTC_GLYPH_NODE(node)->item_start);
+
+      if ( anode )
+      {
+        *anode = FTC_NODE(node);
+        FTC_NODE(node)->ref_count ++;
+      }
     }
     return error;
   }
+
+
+
+ /* backwards-compatibility functions */
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_SBit_Cache_New( FTC_Manager      manager,
+                      FTC_SBit_Cache  *acache )
+  {
+    return FTC_SBitCache_New( manager, (FTC_SBitCache*)acache );
+  }
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_SBit_Cache_Lookup( FTC_SBit_Cache   cache,
+                         FTC_Image_Desc*  desc,
+                         FT_UInt          gindex,
+                         FTC_SBit        *ansbit )
+  {
+    FTC_ImageDesc  desc0;
+    
+    if ( !desc )
+      return FT_Err_Invalid_Argument;
+      
+    desc0.font = desc->font;
+    desc0.type = (FT_UInt32) desc->image_type;
+
+    return FTC_SBitCache_Lookup( (FTC_SBitCache)cache,
+                                  &desc0,
+                                  gindex,
+                                  ansbit,
+                                  NULL );
+  }
+
 
 
 /* END */
--- a/src/cache/ftlru.c
+++ b/src/cache/ftlru.c
@@ -46,7 +46,7 @@
       list->clazz      = clazz;
       list->memory     = memory;
       list->max_nodes  = max_nodes;
-      list->user_data  = user_data;
+      list->data  = user_data;
 
       if ( clazz->list_init )
       {
@@ -110,7 +110,7 @@
 
 
       if ( clazz->node_done )
-        clazz->node_done( node, list );
+        clazz->node_done( node, list->data );
 
       FREE( node );
       node = next;
@@ -151,7 +151,7 @@
         if ( node == NULL )
           break;
 
-        if ( clazz->node_compare( node, key, list ) )
+        if ( clazz->node_compare( node, key, list->data ) )
           break;
 
         plast = pnode;
@@ -203,15 +203,15 @@
       {
         if ( clazz->node_flush )
         {
-          error = clazz->node_flush( last, key, list );
+          error = clazz->node_flush( last, key, list->data );
         }
         else
         {
           if ( clazz->node_done )
-            clazz->node_done( last, list );
+            clazz->node_done( last, list->data );
 
           last->key  = key;
-          error = clazz->node_init( last, key, list );
+          error = clazz->node_init( last, key, list->data );
         }
 
         if ( !error )
@@ -228,7 +228,7 @@
         /* in case of error during the flush or done/init cycle, */
         /* we need to discard the node                           */
         if ( clazz->node_done )
-          clazz->node_done( last, list );
+          clazz->node_done( last, list->data );
 
         *plast = NULL;
         list->num_nodes--;
@@ -243,7 +243,7 @@
       goto Exit;
 
     node->key = key;
-    error = clazz->node_init( node, key, list );
+    error = clazz->node_init( node, key, list->data );
     if ( error )
     {
       FREE( node );
@@ -284,7 +284,7 @@
         node->next = NULL;
 
         if ( clazz->node_done )
-          clazz->node_done( node, list );
+          clazz->node_done( node, list->data );
 
         FREE( node );
         list->num_nodes--;
@@ -319,7 +319,7 @@
       if ( node == NULL )
         break;
 
-      if ( select_func( node, select_data, list ) )
+      if ( select_func( node, select_data, list->data ) )
       {
         *pnode     = node->next;
         node->next = NULL;
--- a/src/cache/rules.mk
+++ b/src/cache/rules.mk
@@ -30,8 +30,8 @@
 #
 Cache_DRV_SRC := $(CACHE_DIR_)ftlru.c    \
                  $(CACHE_DIR_)ftcmanag.c \
+                 $(CACHE_DIR_)ftccache.c \
                  $(CACHE_DIR_)ftcglyph.c \
-                 $(CACHE_DIR_)ftcchunk.c \
                  $(CACHE_DIR_)ftcsbits.c \
                  $(CACHE_DIR_)ftcimage.c
 
--- a/src/pshinter/pshalgo1.c
+++ b/src/pshinter/pshalgo1.c
@@ -220,7 +220,7 @@
 
 
       FT_ERROR(( "%s.init: missing/incorrect hint masks!\n" ));
-      count = table->max_hints;
+      Count = table->max_hints;
       for ( Index = 0; Index < Count; Index++ )
         psh1_hint_table_record( table, Index );
     }
--- a/src/pshinter/pshalgo2.c
+++ b/src/pshinter/pshalgo2.c
@@ -217,7 +217,7 @@
 
 
       FT_ERROR(( "%s.init: missing/incorrect hint masks!\n" ));
-      count = table->max_hints;
+      Count = table->max_hints;
       for ( Index = 0; Index < Count; Index++ )
         psh2_hint_table_record( table, Index );
     }
@@ -1495,15 +1495,12 @@
                    FT_Outline*  outline,
                    PSH_Globals  globals )
   {
-    PSH2_Glyph     glyph;
     PSH2_GlyphRec  glyphrec;
+    PSH2_Glyph     glyph = &glyphrec;
     FT_Error       error;
     FT_Memory      memory;
     FT_Int         dimension;
 
-    FT_UNUSED(glyphrec);
-
-
     memory = globals->memory;
 
 #ifdef DEBUG_HINTER
@@ -1517,8 +1514,6 @@
       return error;
 
     ps2_debug_glyph = glyph;
-#else
-    glyph = &glyphrec;
 #endif
 
     error = psh2_glyph_init( glyph, outline, ps_hints, globals );