shithub: freetype+ttf2subf

Download patch

ref: ece6379859b2275bec4d39df2e9eb9443fb94a68
parent: b5084e11f7d2d73e0687dee6314c560b8fe6d4cb
author: David Turner <[email protected]>
date: Sat Oct 28 19:34:45 EDT 2000

completed the sbit cache, though it's still buggy :-(
major reformatting of the cache subsystem (again)
added substantial documentation too in header files

git/fs: mount .git/fs: mount/attach disallowed
--- a/include/freetype/cache/ftcchunk.h
+++ b/include/freetype/cache/ftcchunk.h
@@ -58,11 +58,11 @@
 #define  FTC_MAX_CHUNK_SETS  16
 
 
-  typedef struct FTC_ChunkRec_*        FTC_Chunk;
+  typedef struct FTC_ChunkNodeRec_*    FTC_ChunkNode;
   typedef struct FTC_ChunkSetRec_*     FTC_ChunkSet;
   typedef struct FTC_Chunk_CacheRec_*  FTC_Chunk_Cache;
 
-  typedef struct FTC_ChunkRec_
+  typedef struct FTC_ChunkNodeRec_
   {
     FTC_CacheNodeRec    root;
     FTC_ChunkSet        cset;
@@ -70,8 +70,10 @@
     FT_UShort           num_elements;
     FT_Byte*            elements;
   
-  } FTC_ChunkRec;
+  } FTC_ChunkNodeRec;
 
+#define FTC_CHUNKNODE_TO_LRUNODE(x)  ((FT_ListNode)(x))
+#define FTC_LRUNODE_TO_CHUNKNODE(x)  ((FTC_ChunkNode)(x))
 
   /*************************************************************************/
   /*                                                                       */
@@ -78,6 +80,11 @@
   /*  chunk set methods                                                    */
   /*                                                                       */
 
+ /* used to set "element_max", "element_count" and "element_size" */
+  typedef FT_Error  (*FTC_ChunkSet_SizesFunc)  ( FTC_ChunkSet   cset,
+                                                 FT_Pointer     type );
+
+
   typedef FT_Error  (*FTC_ChunkSet_InitFunc)  ( FTC_ChunkSet   cset,
                                                 FT_Pointer     type );
 
@@ -100,11 +107,12 @@
 
   typedef struct  FTC_ChunkSet_Class_
   {
-    FT_UInt                       cset_size;
+    FT_UInt                       cset_byte_size;
 
     FTC_ChunkSet_InitFunc         init;
     FTC_ChunkSet_DoneFunc         done;
     FTC_ChunkSet_CompareFunc      compare;
+    FTC_ChunkSet_SizesFunc        sizes;
 
     FTC_ChunkSet_NewNodeFunc      new_node;
     FTC_ChunkSet_SizeNodeFunc     size_node;
@@ -119,11 +127,12 @@
     FTC_Manager          manager;
     FT_Memory            memory;
     FTC_ChunkSet_Class*  clazz;
-    FT_UInt              cset_index;  /* index in parent cache    */
+    FT_UInt              cset_index;     /* index in parent cache    */
 
     FT_UInt              element_max;    /* maximum number of elements   */
     FT_UInt              element_size;   /* element size in bytes        */
     FT_UInt              element_count;  /* number of elements per chunk */
+
     FT_UInt              num_chunks;
     FTC_ChunkNode*       chunks;
 
@@ -145,7 +154,7 @@
     FTC_CacheRec     root;
     FT_Lru           csets_lru;  /* static chunk set lru list */
     FTC_ChunkSet     last_cset;  /* small cache :-)           */
-
+    
   } FTC_Chunk_CacheRec;
 
   /*************************************************************************/
@@ -155,7 +164,7 @@
   /* cache sub-system internals.                                           */
   /*                                                                       */
 
-  FT_EXPORT_FUNC( NV_Error )
+  FT_EXPORT_FUNC( FT_Error )
   FTC_ChunkNode_Init( FTC_ChunkNode  node,
                       FTC_ChunkSet   cset,
                       FT_UInt        index,
@@ -186,10 +195,7 @@
   FT_EXPORT_DEF( FT_Error )
   FTC_ChunkSet_New( FTC_Chunk_Cache   cache,
                     FT_Pointer        type,
-                    FT_UInt           num_elements,
-                    FT_UInt           element_size,
-                    FT_UInt           chunk_size,
-                    FTC_ChunkSet     *aset )
+                    FTC_ChunkSet     *aset );
 
 
   FT_EXPORT_DEF( FT_Error )
--- a/include/freetype/cache/ftcglyph.h
+++ b/include/freetype/cache/ftcglyph.h
@@ -2,7 +2,7 @@
 /*                                                                         */
 /*  ftcglyph.h                                                             */
 /*                                                                         */
-/*    FreeType glyph image (FT_Glyph) cache (specification).               */
+/*    FreeType abstract glyph cache (specification).                       */
 /*                                                                         */
 /*  Copyright 2000 by                                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
@@ -24,6 +24,14 @@
   /*            For example, see `ftcimage.h' and `ftcimage.c' which       */
   /*            implement a FT_Glyph cache based on this code.             */
   /*                                                                       */
+  /*  NOTE: for now, each glyph set is implemented as a static hash table  */
+  /*        it's be interesting to experiment with dynamic hashes to see   */
+  /*        if this improves performance or not (I don't know why but      */
+  /*        something tells me it won't ?!)                                */
+  /*                                                                       */
+  /*        in all cases, this change should not affect any derived        */
+  /*        glyph cache class..                                            */
+  /*                                                                       */
   /*************************************************************************/
 
 
@@ -147,7 +155,7 @@
   {
     FTC_CacheRec  root;
     FT_Lru        gsets_lru;  /* static sets lru list */
-    FTC_GlyphSet  last_gset;  /* small cache :-)        */
+    FTC_GlyphSet  last_gset;  /* small cache :o)      */
 
   } FTC_Glyph_CacheRec;
 
--- /dev/null
+++ b/include/freetype/cache/ftcimage.h
@@ -1,0 +1,190 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftcimage.c                                                             */
+/*                                                                         */
+/*    FreeType Image cache (body).                                         */
+/*                                                                         */
+/*  Each image cache really manages FT_Glyph objects :-)                   */
+/*                                                                         */
+/*                                                                         */
+/*  Copyright 2000 by                                                      */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef FTCIMAGE_H
+#define FTCIMAGE_H
+
+
+#include <freetype/cache/ftcglyph.h>
+#include <freetype/ftglyph.h>
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                       IMAGE CACHE OBJECT                      *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+#define  FTC_IMAGE_FORMAT( x )  ( (x) & 7 )
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Enum>                                                                */
+  /*    FTC_Image_Type                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An enumeration used to list the types of glyph images found in a   */
+  /*    glyph image cache.                                                 */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    ftc_image_mono     :: Monochrome bitmap glyphs.                    */
+  /*                                                                       */
+  /*    ftc_image_grays    :: Anti-aliased bitmap glyphs.                  */
+  /*                                                                       */
+  /*    ftc_image_outline  :: Scaled (and hinted) outline glyphs.          */
+  /*                                                                       */
+  /*    ftc_master_outline :: Unscaled original outline glyphs.            */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Other types may be defined in the future.                          */
+  /*                                                                       */
+  typedef enum  FTC_Image_Type_
+  {
+    ftc_image_format_bitmap   = 0,
+    ftc_image_format_outline  = 1,
+
+    ftc_image_flag_monochrome = 16,
+    ftc_image_flag_unhinted   = 32,
+    ftc_image_flag_autohinted = 64,
+    ftc_image_flag_unscaled   = 128,
+    ftc_image_flag_no_sbits   = 256,
+
+    ftc_image_mono    = ftc_image_format_bitmap |
+                        ftc_image_flag_monochrome, /* monochrome bitmap   */
+    ftc_image_grays   = ftc_image_format_bitmap,   /* anti-aliased bitmap */
+    ftc_image_outline = ftc_image_format_outline   /* scaled outline */
+
+  } FTC_Image_Type;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FTC_Image_Desc                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure used to describe a given glyph image category.  */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    size       :: An FTC_SizeRec used to describe the glyph's face &   */
+  /*                  size.                                                */
+  /*                                                                       */
+  /*    image_type :: The glyph image's type.                              */
+  /*                                                                       */
+  typedef struct  FTC_Image_Desc_
+  {
+    FTC_FontRec  font;
+    FT_UInt      image_type;
+
+  } FTC_Image_Desc;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    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.                                                  */
+  /*                                                                       */
+  typedef struct FTC_Image_CacheRec_*  FTC_Image_Cache;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FTC_Image_Cache_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_DEF( FT_Error )  FTC_Image_Cache_New( FTC_Manager       manager,
+                                                  FTC_Image_Cache*  acache );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FTC_Image_Cache_Lookup                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Retrieves a given glyph image from a glyph image cache.            */
+  /*                                                                       */
+  /* <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.                                                 */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    error code, 0 means success                                        */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    the returned glyph is owned and manager 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.         */
+  /*                                                                       */
+  /*    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_DEF( FT_Error )
+  FTC_Image_Cache_Lookup( FTC_Image_Cache  cache,
+                          FTC_Image_Desc*  desc,
+                          FT_UInt          gindex,
+                          FT_Glyph*        aglyph );
+
+
+
+#ifdef __cplusplus
+  }
+#endif
+
+
+#endif /* FTCIMAGE_H */
+
+
+/* END */
--- a/include/freetype/cache/ftcmanag.h
+++ b/include/freetype/cache/ftcmanag.h
@@ -73,7 +73,6 @@
 #endif
 
 
-  /* default values */
 #define FTC_MAX_FACES_DEFAULT  2
 #define FTC_MAX_SIZES_DEFAULT  4
 #define FTC_MAX_BYTES_DEFAULT  200000  /* 200kByte by default! */
@@ -82,6 +81,40 @@
 #define FTC_MAX_CACHES         16
 
 
+ /****************************************************************
+  *
+  * <Struct> FTC_ManagerRec
+  *
+  * <Description>
+  *    the cache manager structure. Each cache manager is in
+  *    charge of performing two tasks:
+  *
+  * <Fields>
+  *    library     :: handle to FreeType library instance
+  *    faces_lru   :: lru list of FT_Face objects in cache
+  *    sizes_lru   :: lru list of FT_Size objects in cache
+  *
+  *    max_bytes   :: maximum number of bytes to be allocated
+  *                   in the cache. this is only related to
+  *                   the byte size of the nodes cached by
+  *                   the manager.
+  * 
+  *    num_bytes   :: current number of bytes allocated in
+  *                   the cache. only related to the byte size
+  *                   of cached nodes.
+  *
+  *    num_nodes   :: current number of nodes in the manager
+  *
+  *    global_lru  :: the global lru list of all cache nodes
+  *
+  *    caches      :: a table of installed/registered cache
+  *                   objects
+  *
+  *    request_data :: user-provided data passed to the requester
+  *    request_face :: user-provided function used to implement
+  *                    a mapping between abstract FTC_FaceIDs
+  *                    and real FT_Face objects..
+  */
   typedef struct  FTC_ManagerRec_
   {
     FT_Library          library;
@@ -90,6 +123,7 @@
 
     FT_ULong            max_bytes;
     FT_ULong            num_bytes;
+    FT_UInt             num_nodes;
     FT_ListRec          global_lru;
     FTC_Cache           caches[FTC_MAX_CACHES];
 
@@ -99,6 +133,31 @@
   } FTC_ManagerRec;
 
 
+ /**********************************************************************
+  *
+  * <Function> FTC_Manager_Compress
+  *
+  * <Description>
+  *    this function is used to check the state of the cache manager
+  *    if its "num_bytes" field is greater than its "max_bytes"
+  *    field, this function will flush as many old cache nodes as
+  *    possible (ignoring cache nodes with a non-zero reference
+  *    count).
+  *
+  * <input>
+  *    manager ::  handle to cache manager
+  *
+  * <note>
+  *    client applications should not call this function directly.
+  *    it is normally invoked by specific cache implementations.
+  *
+  *    the reason this function is exported is to allow client-
+  *    specific cache classes..
+  *
+  */
+  FT_EXPORT_DEF( void )  FTC_Manager_Compress( FTC_Manager  manager );
+
+
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -138,19 +197,56 @@
 
 #define FTC_LIST_TO_CACHENODE( n )  ( (FTC_CacheNode)(n) )
 
-  /* return the size in bytes of a given cache node */
+ /**********************************************************************
+  *
+  * <FuncType> FTC_CacheNode_SizeFunc
+  *
+  * <Description>
+  *    a function used to compute the total size in bytes of a given
+  *    cache node. It is used by the cache manager to compute the
+  *    number of old nodes to flush when the cache is full..
+  *
+  * <Input>
+  *    node       :: handle to target cache node
+  *    cache_data :: a generic pointer passed to the destructor.
+  */
   typedef FT_ULong  (*FTC_CacheNode_SizeFunc)( FTC_CacheNode  node,
-                                               FT_Pointer     user );
+                                               FT_Pointer     cache_data );
 
-  /* finalize a given cache node */
+ /**********************************************************************
+  *
+  * <FuncType> FTC_CacheNode_DestroyFunc
+  *
+  * <Description>
+  *    a function used to destroy a given cache node. It is called
+  *    by the manager when the cache is full and old nodes need to
+  *    be flushed out..
+  *
+  * <Input>
+  *    node       :: handle to target cache node
+  *    cache_data :: a generic pointer passed to the destructor.
+  */
   typedef void  (*FTC_CacheNode_DestroyFunc)( FTC_CacheNode  node,
-                                              FT_Pointer     user );
+                                              FT_Pointer     cache_data );
 
-  /* This structure is used to provide functions to the cache manager.  */
-  /* It will use them to size and destroy cache nodes.  Note that there */
-  /* is no `init_node' because cache objects are entirely responsible   */
-  /* for the creation of new cache nodes.                               */
-  /*                                                                    */
+ /**********************************************************************
+  *
+  * <Struct> FTC_CacheNode_Class
+  *
+  * <Description>
+  *    a very simple structure used to describe a cache node's class
+  *    to the cache manager
+  *
+  * <Fields>
+  *    size_node    :: a function used to size the node
+  *    destroy_node :: a function used to destroy the node
+  *
+  * <Note>
+  *    the cache node class doesn't include a "new_node" function
+  *    because the cache manager never allocates cache node directly,
+  *    it delegates this task to its cache objects..
+  *
+  */
   typedef struct  FTC_CacheNode_Class_
   {
     FTC_CacheNode_SizeFunc     size_node;
@@ -168,10 +264,45 @@
   /*************************************************************************/
 
 
+ /**********************************************************************
+  *
+  * <FuncType> FTC_Cache_InitFunc
+  *
+  * <Description>
+  *    a function used to initialize a given cache object
+  *
+  * <Input>
+  *    cache  :: handle to new cache
+  */
   typedef FT_Error  (*FTC_Cache_InitFunc)( FTC_Cache  cache );
+
+
+ /**********************************************************************
+  *
+  * <FuncType> FTC_Cache_DoneFunc
+  *
+  * <Description>
+  *    a function used to finalize a given cache object
+  *
+  * <Input>
+  *    cache  :: handle to target cache
+  */
   typedef void      (*FTC_Cache_DoneFunc)( FTC_Cache  cache );
 
 
+ /**********************************************************************
+  *
+  * <Struct> FTC_Cache_Class
+  *
+  * <Description>
+  *    a structure used to describe a given cache object class to
+  *    the cache manager.
+  *
+  * <Fields>
+  *    cache_byte_size  :: size of cache object in bytes
+  *    init_cache       :: cache object initializer
+  *    done_cache       :: cache object finalizer
+  */
   struct  FTC_Cache_Class_
   {
     FT_UInt             cache_byte_size;
@@ -179,6 +310,23 @@
     FTC_Cache_DoneFunc  done_cache;
   };
 
+
+ /**********************************************************************
+  *
+  * <Struct> FTC_CacheRec
+  *
+  * <Description>
+  *    a structure used to describe an abstract cache object
+  *
+  * <Fields>
+  *    manager     :: handle to parent cache manager
+  *    memory      :: handle to memory manager
+  *    clazz       :: pointer to cache clazz
+  *    node_clazz  :: pointer to cache's node clazz
+  *
+  *    cache_index :: index of cache in manager's table
+  *    cache_data  :: data passed to the cache node constructor/finalizer
+  */
   typedef struct  FTC_CacheRec_
   {
     FTC_Manager           manager;
@@ -187,15 +335,10 @@
     FTC_CacheNode_Class*  node_clazz;
 
     FT_UInt               cache_index;  /* in manager's table           */
-    FT_Pointer            cache_user;   /* passed to cache node methods */
+    FT_Pointer            cache_data;   /* passed to cache node methods */
 
   } FTC_CacheRec;
 
-
-  /* `Compress' the manager's data, i.e., get rid of old cache nodes */
-  /* that are not referenced anymore in order to limit the total     */
-  /* memory used by the cache.                                       */
-  FT_EXPORT_DEF( void )  FTC_Manager_Compress( FTC_Manager  manager );
 
 
 #ifdef __cplusplus
--- /dev/null
+++ b/include/freetype/cache/ftcsbits.h
@@ -1,0 +1,73 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftcsbits.h                                                             */
+/*                                                                         */
+/*    a small-bitmaps cache (specification).                               */
+/*                                                                         */
+/*  Copyright 2000 by                                                      */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+#ifndef FTCSBITS_H
+#define FTCSBITS_H
+
+#include <freetype/cache/ftcchunk.h> 
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+ /* handle to small bitmap */
+  typedef struct FTC_SBitRec_*   FTC_SBit;
+
+
+ /* handle to small bitmap cache */
+  typedef struct FTC_SBit_CacheRec_*   FTC_SBit_Cache;
+
+
+ /* a compact structure used to hold a single small bitmap */  
+  typedef struct FTC_SBitRec_
+  {
+    FT_Byte   width;
+    FT_Byte   height;
+    FT_Char   left;
+    FT_Char   top;
+
+    FT_Byte   format;
+    FT_Char   pitch;
+    FT_Char   xadvance;
+    FT_Char   yadvance;
+
+    FT_Byte*  buffer;
+  
+  } FTC_SBitRec;
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_SBit_Cache_New( FTC_Manager      manager,
+                      FTC_SBit_Cache  *acache );
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FTC_SBit_Cache_Lookup( FTC_SBit_Cache   cache,
+                         FTC_Image_Desc*  desc,
+                         FT_UInt          gindex,
+                         FTC_SBit        *sbit );
+
+
+#ifdef __cplusplus
+  }
+#endif
+
+
+#endif /* FTCSBITS_H */
+
+/* END */
+
--- a/include/freetype/cache/ftlru.h
+++ b/include/freetype/cache/ftlru.h
@@ -72,7 +72,7 @@
   typedef FT_Pointer  FT_LruKey;
 
 
-  /* an lru node -- node.root.data points to the element */
+  /* an lru node -- root.data points to the element */
   typedef struct  FT_LruNodeRec_
   {
     FT_ListNodeRec  root;
@@ -80,6 +80,8 @@
   
   } FT_LruNodeRec, *FT_LruNode;
 
+
+
   /* forward declaration */
   typedef struct FT_LruRec_*  FT_Lru;
 
@@ -94,8 +96,8 @@
                                FT_LruNode  node );
                                
     /* this method is used to finalize a given list element node */
-    void  (*done_element)( FT_Lru      lru,
-                           FT_LruNode  node );
+    void      (*done_element)( FT_Lru      lru,
+                               FT_LruNode  node );
     
     /* If defined, this method is called when the list if full        */
     /* during the lookup process -- it is used to change the contents */
@@ -145,11 +147,12 @@
                                          FT_Memory            memory,
                                          FT_Bool              pre_alloc,
                                          FT_Lru*              alru );
-                                          
-  FT_EXPORT_DEF( void )  FT_Lru_Reset( FT_Lru  lru ); 
-                                       
-  FT_EXPORT_DEF( void )  FT_Lru_Done( FT_Lru  lru ); 
 
+  FT_EXPORT_DEF( void )      FT_Lru_Reset( FT_Lru  lru ); 
+
+  FT_EXPORT_DEF( void )      FT_Lru_Done ( FT_Lru  lru ); 
+
+
   FT_EXPORT_DEF( FT_Error )  FT_Lru_Lookup_Node( FT_Lru        lru,
                                                  FT_LruKey     key,
                                                  FT_LruNode*  anode );
@@ -157,7 +160,8 @@
   FT_EXPORT_DEF( FT_Error )  FT_Lru_Lookup( FT_Lru       lru,
                                             FT_LruKey    key,
                                             FT_Pointer*  aobject );
- 
+
+
   FT_EXPORT_DEF( void )  FT_Lru_Remove_Node( FT_Lru      lru,
                                              FT_LruNode  node );  
 
--- a/include/freetype/ftcache.h
+++ b/include/freetype/ftcache.h
@@ -90,6 +90,11 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    the face requester should not perform funny things on the returned */
+  /*    face object, like creating a new FT_Size for it, or setting a      */
+  /*    transform through FT_Set_Transform !!                              */
+  /*                                                                       */
   typedef FT_Error  (*FTC_Face_Requester)( FTC_FaceID  face_id,
                                            FT_Library  library,
                                            FT_Pointer  request_data,
@@ -307,8 +312,8 @@
                                                       FTC_Font     font,
                                                       FT_Face*     aface,
                                                       FT_Size*     asize );
+  
 
-
   /* a cache class is used to describe a unique cache type to the manager */
   typedef struct FTC_Cache_Class_  FTC_Cache_Class;
   typedef struct FTC_CacheRec_*    FTC_Cache;
@@ -319,153 +324,6 @@
                                FTC_Manager       manager,
                                FTC_Cache_Class*  clazz,
                                FTC_Cache*        acache );
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                       IMAGE CACHE OBJECT                      *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-#define  FTC_IMAGE_FORMAT( x )  ( (x) & 7 )
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Enum>                                                                */
-  /*    FTC_Image_Type                                                     */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    An enumeration used to list the types of glyph images found in a   */
-  /*    glyph image cache.                                                 */
-  /*                                                                       */
-  /* <Fields>                                                              */
-  /*    ftc_image_mono     :: Monochrome bitmap glyphs.                    */
-  /*                                                                       */
-  /*    ftc_image_grays    :: Anti-aliased bitmap glyphs.                  */
-  /*                                                                       */
-  /*    ftc_image_outline  :: Scaled (and hinted) outline glyphs.          */
-  /*                                                                       */
-  /*    ftc_master_outline :: Unscaled original outline glyphs.            */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    Other types may be defined in the future.                          */
-  /*                                                                       */
-  typedef enum  FTC_Image_Type_
-  {
-    ftc_image_format_bitmap   = 0,
-    ftc_image_format_outline  = 1,
-
-    ftc_image_flag_monochrome = 16,
-    ftc_image_flag_unhinted   = 32,
-    ftc_image_flag_autohinted = 64,
-    ftc_image_flag_unscaled   = 128,
-    ftc_image_flag_no_sbits   = 256,
-
-    ftc_image_mono    = ftc_image_format_bitmap |
-                        ftc_image_flag_monochrome, /* monochrome bitmap   */
-    ftc_image_grays   = ftc_image_format_bitmap,   /* anti-aliased bitmap */
-    ftc_image_outline = ftc_image_format_outline   /* scaled outline */
-
-  } FTC_Image_Type;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Struct>                                                              */
-  /*    FTC_Image_Desc                                                     */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A simple structure used to describe a given glyph image category.  */
-  /*                                                                       */
-  /* <Fields>                                                              */
-  /*    size       :: An FTC_SizeRec used to describe the glyph's face &   */
-  /*                  size.                                                */
-  /*                                                                       */
-  /*    image_type :: The glyph image's type.                              */
-  /*                                                                       */
-  typedef struct  FTC_Image_Desc_
-  {
-    FTC_FontRec  font;
-    FT_UInt      image_type;
-
-  } FTC_Image_Desc;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    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.                                                  */
-  /*                                                                       */
-  typedef struct FTC_Image_CacheRec_*  FTC_Image_Cache;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    FTC_Image_Cache_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_DEF( FT_Error )  FTC_Image_Cache_New( FTC_Manager       manager,
-                                                  FTC_Image_Cache*  acache );
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    FTC_Image_Cache_Lookup                                             */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Retrieves a given glyph image from a glyph image cache.            */
-  /*                                                                       */
-  /* <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.                                                 */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    error code, 0 means success                                        */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    the returned glyph is owned and manager 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.         */
-  /*                                                                       */
-  /*    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_DEF( FT_Error )
-  FTC_Image_Cache_Lookup( FTC_Image_Cache  cache,
-                          FTC_Image_Desc*  desc,
-                          FT_UInt          gindex,
-                          FT_Glyph*        aglyph );
 
 
 #ifdef __cplusplus
--- a/src/cache/ftcache.c
+++ b/src/cache/ftcache.c
@@ -23,7 +23,9 @@
 #include "ftlru.c"
 #include "ftcmanag.c"
 #include "ftcglyph.c"
+#include "ftcchunk.c"
 #include "ftcimage.c"
+#include "ftcsbits.c"
 
 #else
 
@@ -30,7 +32,9 @@
 #include <cache/ftlru.c>
 #include <cache/ftcmanag.c>
 #include <cache/ftcglyph.c>
+#include <cache/ftcchunk.c>
 #include <cache/ftcimage.c>
+#include <cache/ftcsbits.c>
 
 #endif
 
--- a/src/cache/ftcchunk.c
+++ b/src/cache/ftcchunk.c
@@ -16,7 +16,7 @@
 /***************************************************************************/
 
 
-#include <freetype/cache/ftcglyph.h>
+#include <freetype/cache/ftcchunk.h>
 #include <freetype/fterrors.h>
 #include <freetype/internal/ftobjs.h>
 #include <freetype/internal/ftlist.h>
@@ -33,7 +33,7 @@
 
 
   /* create a new chunk node, setting its cache index and ref count */
-  FT_EXPORT_FUNC( NV_Error )
+  FT_EXPORT_FUNC( FT_Error )
   FTC_ChunkNode_Init( FTC_ChunkNode  node,
                       FTC_ChunkSet   cset,
                       FT_UInt        index,
@@ -41,7 +41,7 @@
   {
     FTC_Chunk_Cache      cache = cset->cache;
     FTC_CacheNode_Data*  data  = FTC_CACHENODE_TO_DATA_P( &node->root );
-    NV_Error             error = 0;
+    FT_Error             error = 0;
 
 
     data->cache_index = (FT_UShort) cache->root.cache_index;
@@ -48,15 +48,18 @@
     data->ref_count   = (FT_Short)  0;
     node->cset_index  = (FT_UShort) index;
 
-    node->num_elements = (index+1 < cset->chunk_count)
-                       ? cset->chunk_size
-                       : cset->element_max - cset->chunk_count*index;
+    node->num_elements = (index+1 < cset->element_count)
+                       ? cset->element_count * cset->element_size
+                       : cset->element_max   - cset->element_count*index;
     if (alloc)
     {
       /* allocate elements array */
+      FT_Memory   memory;
+
+      
       memory = cache->root.memory;
-      error  = MEM_ALLOC( cache->elements, cset->element_size *
-                                           cset->element_count );
+      error  = MEM_Alloc( node->elements, cset->element_size *
+                                          cset->element_count );
     }
     return error;
   }
@@ -79,7 +82,7 @@
     FTC_ChunkSet  cset     = node->cset;
 
 
-    return cset->clazz->size_node( node, cset );
+    return cset->clazz->size_node( node );
   }
 
 
@@ -102,9 +105,6 @@
   FT_EXPORT_FUNC( FT_Error )
   FTC_ChunkSet_New( FTC_Chunk_Cache   cache,
                     FT_Pointer        type,
-                    FT_UInt           num_elements,
-                    FT_UInt           element_size,
-                    FT_UInt           chunk_size,
                     FTC_ChunkSet     *aset )
   {
     FT_Error      error;
@@ -121,19 +121,22 @@
 
     *aset = 0;
 
-    if ( ALLOC( set, clazz->cset_byte_size ) )
+    if ( ALLOC( cset, clazz->cset_byte_size ) )
       goto Exit;
 
     cset->cache         = cache;
     cset->manager       = manager;
     cset->memory        = memory;
-    cset->element_max   = num_elements;
-    cset->element_size  = element_size;
-    cset->element_count = chunk_size;
     cset->clazz         = clazz;
 
+    /* now compute element_max, element_count and element_size */
+    error = clazz->sizes( cset, type);
+    if (error)
+      goto Exit;
+
     /* compute maximum number of nodes */
-    cset->num_chunks = (num_elements + (chunk_size-1))/chunk_size;
+    cset->num_chunks = (cset->element_max   + 
+                        cset->element_count - 1) / cset->element_count;
 
     /* allocate chunk pointers table */
     if ( ALLOC_ARRAY( cset->chunks, cset->num_chunks, FTC_ChunkNode ) )
@@ -165,7 +168,7 @@
     FTC_Chunk_Cache         cache        = cset->cache;
     FTC_Manager             manager      = cache->root.manager;
     FT_List                 glyphs_lru   = &manager->global_lru;
-    FTC_ChunkNode*          bucket       = cset->chunk;
+    FTC_ChunkNode*          bucket       = cset->chunks;
     FTC_ChunkNode*          bucket_limit = bucket + cset->num_chunks;
     FT_Memory               memory       = cache->root.memory;
 
@@ -181,6 +184,7 @@
       lrunode = FTC_CHUNKNODE_TO_LRUNODE( node );
 
       manager->num_bytes -= clazz->size_node( node );
+      manaher->num_nodes --;
 
       FT_List_Remove( glyphs_lru, lrunode );
 
@@ -201,21 +205,21 @@
   FTC_ChunkSet_Lookup_Node( FTC_ChunkSet    cset,
                             FT_UInt         glyph_index,
                             FTC_ChunkNode  *anode,
-                            FTC_UInt       *index )
+                            FT_UInt        *aindex )
   {
-    FTC_Glyph_Cache  cache   = cset->cache;
+    FTC_Chunk_Cache  cache   = cset->cache;
     FTC_Manager      manager = cache->root.manager;
     FT_Error         error   = 0;
 
-    FTC_GlyphSet_Class*  clazz = cset->clazz;
+    FTC_ChunkSet_Class*  clazz = cset->clazz;
 
 
     *anode = 0;
-    if (glyph_index >= cset->elements_max)
+    if (glyph_index >= cset->element_max)
       error = FT_Err_Invalid_Argument;
     else
     {
-      FT_UInt         chunk_size  = cset->chunk_size;
+      FT_UInt         chunk_size  = cset->element_count;
       FT_UInt         chunk_index = glyph_index/chunk_size;
       FTC_ChunkNode*  pnode       = cset->chunks + chunk_index;
       FTC_ChunkNode   node        = *pnode;
@@ -233,7 +237,8 @@
         /* insert the node at the start the global LRU glyph list */
         FT_List_Insert( &manager->global_lru, FTC_CHUNKNODE_TO_LRUNODE( node ) );
 
-        manager->num_bytes += clazz->size_node( node, gset );
+        manager->num_bytes += clazz->size_node( node );
+        manager->num_nodes ++;
 
         if (manager->num_bytes > manager->max_bytes)
         {
@@ -287,7 +292,7 @@
     {
       /* good, now set the set index within the set object */
       cset->cset_index = node - lru->nodes;
-      node->root.data  = set;
+      node->root.data  = cset;
     }
 
     return error;
@@ -347,15 +352,8 @@
     cache->root.node_clazz =
       (FTC_CacheNode_Class*)&ftc_chunk_cache_node_class;
 
-    /* The following is extremely important for ftc_destroy_glyph_image() */
-    /* to work properly, as the second parameter that is sent to it       */
-    /* through the cache manager is `user_data' and must be set to        */
-    /* `cache' here.                                                      */
-    /*                                                                    */
-    cache->root.cache_user = cache;
-
     error = FT_Lru_New( &ftc_chunk_set_lru_class,
-                        FTC_MAX_GLYPH_CSETS,
+                        FTC_MAX_CHUNK_SETS,
                         cache,
                         memory,
                         1, /* pre_alloc == TRUE */
--- a/src/cache/ftcglyph.c
+++ b/src/cache/ftcglyph.c
@@ -50,9 +50,9 @@
 
   /* Important: This function is called from the cache manager to */
   /* destroy a given cache node during `cache compression'.  The  */
-  /* second argument is always `cache.user_data'.  Thus be        */
+  /* second argument is always `cache.cache_data'.  Thus be       */
   /* certain that the function FTC_Glyph_Cache_New() does indeed  */
-  /* set its `user_data' field correctly, otherwise bad things    */
+  /* set its `cache_data' field correctly, otherwise bad things   */
   /* will happen!                                                 */
 
   FT_EXPORT_FUNC( void )  FTC_GlyphNode_Destroy( FTC_GlyphNode    node,
@@ -120,7 +120,7 @@
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
-  /*****                      GLYPH QUEUES                             *****/
+  /*****                      GLYPH SETS                               *****/
   /*****                                                               *****/
   /*************************************************************************/
   /*************************************************************************/
@@ -204,6 +204,7 @@
         lrunode = FTC_GLYPHNODE_TO_LRUNODE( node );
 
         manager->num_bytes -= clazz->size_node( node, gset );
+        manager->num_nodes --;
 
         FT_List_Remove( glyphs_lru, lrunode );
 
@@ -273,6 +274,7 @@
     FT_List_Insert( &manager->global_lru, FTC_GLYPHNODE_TO_LRUNODE( node ) );
 
     manager->num_bytes += clazz->size_node( node, gset );
+    manager->num_nodes ++;
 
     if (manager->num_bytes > manager->max_bytes)
     {
@@ -365,7 +367,7 @@
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
-  /*****                GLYPH IMAGE CACHE OBJECTS                      *****/
+  /*****                      GLYPH CACHE OBJECTS                      *****/
   /*****                                                               *****/
   /*************************************************************************/
   /*************************************************************************/
@@ -383,10 +385,10 @@
 
     /* The following is extremely important for ftc_destroy_glyph_image() */
     /* to work properly, as the second parameter that is sent to it       */
-    /* through the cache manager is `user_data' and must be set to        */
+    /* through the cache manager is `cache_data' and must be set to       */
     /* `cache' here.                                                      */
     /*                                                                    */
-    cache->root.cache_user = cache;
+    cache->root.cache_data = cache;
 
     error = FT_Lru_New( &ftc_glyph_set_lru_class,
                         FTC_MAX_GLYPH_SETS,
--- a/src/cache/ftcimage.c
+++ b/src/cache/ftcimage.c
@@ -16,17 +16,38 @@
 /***************************************************************************/
 
 
-#ifdef FT_FLAT_COMPILE
-#  include "ftcimage.h"
-#else
-#  include <cache/ftcimage.h>
-#endif
+#include <freetype/cache/ftcimage.h>
+#include <freetype/internal/ftmemory.h>
 
 #include <string.h>
 
-#include <freetype/internal/ftmemory.h>
 
+ /* the FT_Glyph image "glyph node" type */
+  typedef struct  FTC_GlyphImageRec_
+  {
+    FTC_GlyphNodeRec   root;
+    FT_Glyph           ft_glyph;
 
+  } FTC_GlyphImageRec, *FTC_GlyphImage;
+
+
+  /* the glyph image queue type */
+  typedef struct  FTC_ImageSetRec_
+  {
+    FTC_GlyphSetRec  root;
+    FTC_Image_Desc   description;
+  
+  } FTC_ImageSetRec, *FTC_ImageSet;
+
+
+  typedef struct  FTC_Image_CacheRec_
+  {
+    FTC_Glyph_CacheRec  root;
+    
+  } FTC_Image_CacheRec;
+
+
+
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -180,7 +201,7 @@
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
-  /*****                    GLYPH IMAGE QUEUES                         *****/
+  /*****                    GLYPH IMAGE SETS                           *****/
   /*****                                                               *****/
   /*************************************************************************/
   /*************************************************************************/
--- a/src/cache/ftcimage.h
+++ b/src/cache/ftcimage.h
@@ -4,6 +4,9 @@
 /*                                                                         */
 /*    FreeType Image cache (body).                                         */
 /*                                                                         */
+/*  Each image cache really manages FT_Glyph objects :-)                   */
+/*                                                                         */
+/*                                                                         */
 /*  Copyright 2000 by                                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
@@ -23,34 +26,157 @@
 #include <freetype/cache/ftcglyph.h>
 #include <freetype/ftglyph.h>
 
-
 #ifdef __cplusplus
   extern "C" {
 #endif
 
- /* the FT_Glyph image "glyph node" type */
-  typedef struct  FTC_GlyphImageRec_
-  {
-    FTC_GlyphNodeRec   root;
-    FT_Glyph           ft_glyph;
 
-  } FTC_GlyphImageRec, *FTC_GlyphImage;
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                       IMAGE CACHE OBJECT                      *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
 
 
-  /* the glyph image queue type */
-  typedef struct  FTC_ImageSetRec_
+#define  FTC_IMAGE_FORMAT( x )  ( (x) & 7 )
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Enum>                                                                */
+  /*    FTC_Image_Type                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An enumeration used to list the types of glyph images found in a   */
+  /*    glyph image cache.                                                 */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    ftc_image_mono     :: Monochrome bitmap glyphs.                    */
+  /*                                                                       */
+  /*    ftc_image_grays    :: Anti-aliased bitmap glyphs.                  */
+  /*                                                                       */
+  /*    ftc_image_outline  :: Scaled (and hinted) outline glyphs.          */
+  /*                                                                       */
+  /*    ftc_master_outline :: Unscaled original outline glyphs.            */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Other types may be defined in the future.                          */
+  /*                                                                       */
+  typedef enum  FTC_Image_Type_
   {
-    FTC_GlyphSetRec  root;
-    FTC_Image_Desc   description;
-  
-  } FTC_ImageSetRec, *FTC_ImageSet;
+    ftc_image_format_bitmap   = 0,
+    ftc_image_format_outline  = 1,
 
+    ftc_image_flag_monochrome = 16,
+    ftc_image_flag_unhinted   = 32,
+    ftc_image_flag_autohinted = 64,
+    ftc_image_flag_unscaled   = 128,
+    ftc_image_flag_no_sbits   = 256,
 
-  typedef struct  FTC_Image_CacheRec_
+    ftc_image_mono    = ftc_image_format_bitmap |
+                        ftc_image_flag_monochrome, /* monochrome bitmap   */
+    ftc_image_grays   = ftc_image_format_bitmap,   /* anti-aliased bitmap */
+    ftc_image_outline = ftc_image_format_outline   /* scaled outline */
+
+  } FTC_Image_Type;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FTC_Image_Desc                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure used to describe a given glyph image category.  */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    size       :: An FTC_SizeRec used to describe the glyph's face &   */
+  /*                  size.                                                */
+  /*                                                                       */
+  /*    image_type :: The glyph image's type.                              */
+  /*                                                                       */
+  typedef struct  FTC_Image_Desc_
   {
-    FTC_Glyph_CacheRec  root;
-    
-  } FTC_Image_CacheRec;
+    FTC_FontRec  font;
+    FT_UInt      image_type;
+
+  } FTC_Image_Desc;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    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.                                                  */
+  /*                                                                       */
+  typedef struct FTC_Image_CacheRec_*  FTC_Image_Cache;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FTC_Image_Cache_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_DEF( FT_Error )  FTC_Image_Cache_New( FTC_Manager       manager,
+                                                  FTC_Image_Cache*  acache );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FTC_Image_Cache_Lookup                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Retrieves a given glyph image from a glyph image cache.            */
+  /*                                                                       */
+  /* <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.                                                 */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    error code, 0 means success                                        */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    the returned glyph is owned and manager 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.         */
+  /*                                                                       */
+  /*    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_DEF( FT_Error )
+  FTC_Image_Cache_Lookup( FTC_Image_Cache  cache,
+                          FTC_Image_Desc*  desc,
+                          FT_UInt          gindex,
+                          FT_Glyph*        aglyph );
+
 
 
 #ifdef __cplusplus
--- a/src/cache/ftcmanag.c
+++ b/src/cache/ftcmanag.c
@@ -54,7 +54,8 @@
     {
       /* destroy initial size object; it will be re-created later */
       face = (FT_Face)node->root.data;
-      FT_Done_Size( face->size );
+      if (face->size)
+        FT_Done_Size( face->size );
     }
 
     return error;
@@ -310,6 +311,7 @@
       FT_Lru_Reset( manager->sizes_lru );
       FT_Lru_Reset( manager->faces_lru );
     }
+    /* FIXME: flush the caches ?? */
   }
 
 
@@ -400,9 +402,9 @@
 
 
           manager->num_bytes -= clazz->size_node( cache_node,
-                                                  cache->cache_user );
+                                                  cache->cache_data );
 
-          clazz->destroy_node( cache_node, cache->cache_user );
+          clazz->destroy_node( cache_node, cache->cache_data );
         }
         else
         {
@@ -409,6 +411,14 @@
           /* this should never happen! */
           FT_ERROR(( "FTC_Manager_Compress: Cache Manager is corrupted!\n" ));
         }
+        
+        /* check, just in case of general corruption :-) */
+        if (manager->num_nodes <= 0)
+        {
+          FT_ERROR(( "FTC_Manager_Compress: invalid cache node count !!\n" ));
+        }
+        else
+          manager->num_nodes--;
       }
       node = prev;
     }
--- a/src/cache/ftcsbits.c
+++ b/src/cache/ftcsbits.c
@@ -1,9 +1,29 @@
-#include <cache/ftcsbits.h>
+#include <freetype/cache/ftcsbits.h>
+#include <freetype/fterrors.h>
 
+#define  FTC_SBITSET_ELEMENT_COUNT  16
+
+
+  typedef struct FTC_SBitSetRec_
+  {
+    FTC_ChunkSetRec   root;
+    FTC_Image_Desc    desc;
+
+  } FTC_SBitSetRec, *FTC_SBitSet;
+
+
+  typedef struct FTC_SBit_CacheRec_
+  {
+    FTC_Chunk_CacheRec    root;
+    
+  } FTC_SBit_CacheRec;
+
+
+
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
-  /*****                    GLYPH IMAGE NODES                          *****/
+  /*****                     SBIT CACHE NODES                          *****/
   /*****                                                               *****/
   /*************************************************************************/
   /*************************************************************************/
@@ -20,10 +40,13 @@
     for ( ; count > 0; sbit++, count-- )
       FREE( sbit->buffer );
 
+    FREE( node->elements );
     FREE( node );
   }
 
 
+
+
   static
   FT_Error  ftc_bitmap_copy( FT_Memory   memory,
                              FT_Bitmap*  source,
@@ -48,12 +71,12 @@
   LOCAL_FUNC_X
   FT_Error  ftc_sbit_chunk_node_new( FTC_ChunkSet   cset,
                                      FT_UInt        index,
-                                     FTC_SBitChunk *anode )
+                                     FTC_ChunkNode *anode )
   {
     FT_Error         error;
     FT_Memory        memory  = cset->memory;
     FTC_SBitSet      sbitset = (FTC_SBitSet)cset;
-    FTC_SBitChunk    node    = 0;
+    FTC_ChunkNode    node    = 0;
     FT_Face          face;
     FT_Size          size;
 
@@ -63,59 +86,59 @@
       goto Exit;
 
     /* init its inner fields */
-    error = FTC_ChunkNode_Init( FTC_CHUNKNODE(node), cset, index, 1 );
+    error = FTC_ChunkNode_Init( node, cset, index, 1 );
     if (error)
       goto Exit;
 
-    /* we will now load all glyph images */
+    /* we will now load all glyph images for this chunk */
     error = FTC_Manager_Lookup_Size( cset->manager,
-                                     &sbitset->description.font,
+                                     &sbitset->desc.font,
                                      &face, &size );
     if ( !error )
     {
-      FT_UInt  glyph_index = index * cset->chunk_size;
+      FT_UInt  glyph_index = index * cset->element_count;
       FT_UInt  load_flags  = FT_LOAD_DEFAULT;
-      FT_UInt  image_type  = sbitset->description.image_type;
+      FT_UInt  image_type  = sbitset->desc.image_type;
       FT_UInt  count       = node->num_elements;
       FTC_SBit sbit        = (FTC_SBit)node->elements;
 
-
-      if ( FTC_IMAGE_FORMAT( image_type ) == ftc_image_format_bitmap )
+      /* determine load flags, depending on the font description's */
+      /* image type..                                              */
       {
-        if ( image_type & ftc_image_flag_monochrome )
-          load_flags |= FT_LOAD_MONOCHROME;
+        if ( FTC_IMAGE_FORMAT( image_type ) == ftc_image_format_bitmap )
+        {
+          if ( image_type & ftc_image_flag_monochrome )
+            load_flags |= FT_LOAD_MONOCHROME;
 
-        /* disable embedded bitmaps loading if necessary */
-        if ( image_type & ftc_image_flag_no_sbits )
-          load_flags |= FT_LOAD_NO_BITMAP;
-      }
-      else if ( FTC_IMAGE_FORMAT( image_type ) == ftc_image_format_outline )
-      {
-        /* disable embedded bitmaps loading */
-        load_flags |= FT_LOAD_NO_BITMAP;
-
-        if ( image_type & ftc_image_flag_unscaled )
+          /* disable embedded bitmaps loading if necessary */
+          if ( image_type & ftc_image_flag_no_sbits )
+            load_flags |= FT_LOAD_NO_BITMAP;
+        }
+        else
         {
-          FT_ERROR(( "FTC_SBit_Cache: cannot load vector outlines in a"
+          FT_ERROR(( "FTC_SBit_Cache: cannot load scalable glyphs in a"
                      " sbit cache, please check your arguments !!\n" ));
-          error = FT_Err_Bad_Argument;
+          error = FT_Err_Invalid_Argument;
           goto Exit;
         }
-      }
 
-      /* always render glyphs to bitmaps */
-      load_flags |= FT_LOAD_RENDER;
+        /* always render glyphs to bitmaps */
+        load_flags |= FT_LOAD_RENDER;
         
-      if ( image_type & ftc_image_flag_unhinted )
-        load_flags |= FT_LOAD_NO_HINTING;
+        if ( image_type & ftc_image_flag_unhinted )
+          load_flags |= FT_LOAD_NO_HINTING;
 
-      if ( image_type & ftc_image_flag_autohinted )
-        load_flags |= FT_LOAD_FORCE_AUTOHINT;
+        if ( image_type & ftc_image_flag_autohinted )
+          load_flags |= FT_LOAD_FORCE_AUTOHINT;
+      }
 
 
       /* load a chunk of small bitmaps in a row */
-      for ( ; count > 0; count--, glyph_index++ )
+      for ( ; count > 0; count--, glyph_index++, sbit++ )
       {
+        /* by default, indicates a "missing" glyph */
+        sbit->buffer = 0;
+        
         error = FT_Load_Glyph( face, glyph_index, load_flags );
         if (!error)
         {
@@ -122,27 +145,37 @@
           FT_Int        temp;
           FT_GlyphSlot  slot   = face->glyph;
           FT_Bitmap*    bitmap = &slot->bitmap;
-          FT_Int        advance;
+          FT_Int        xadvance, yadvance;
 
-          /* check that our values fit in 8-bit containers !! */
-#define  CHECK_SCHAR(d)  ( temp = (FT_SChar)d, temp == d )
-#define  CHECK_BYTE(d)   ( temp = (FT_Byte) d, temp == d )
+          /* check that our values fit in 8-bit containers !!       */
+          /* if this is not the case, our bitmap is too large       */
+          /* and we will leave it as "missing" with sbit.buffer = 0 */
+ 
+#define  CHECK_CHAR(d)   ( temp = (FT_Char)d, temp == d )
+#define  CHECK_BYTE(d)   ( temp = (FT_Byte)d, temp == d )
 
-          advance = (slot->metrics.horiAdvance+32) >> 6;
+          /* FIXME: add support for vertical layouts maybe.. */
+
+          /* horizontal advance in pixels              */
+          xadvance = (slot->metrics.horiAdvance+32) >> 6;
+          yadvance = (slot->metrics.vertAdvance+32) >> 6;
           
           if ( CHECK_BYTE ( bitmap->rows  )     &&
                CHECK_BYTE ( bitmap->width )     &&
-               CHECK_SCHAR( bitmap->pitch )     &&
-               CHECK_SCHAR( slot->bitmap_left ) &&
-               CHECK_SCHAR( slot->bitmap_top  ) &&
-               CHECK_SCHAR( advance )           )
+               CHECK_CHAR ( bitmap->pitch )     &&
+               CHECK_CHAR ( slot->bitmap_left ) &&
+               CHECK_CHAR ( slot->bitmap_top  ) &&
+               CHECK_CHAR ( xadvance )          &&
+               CHECK_CHAR ( yadvance )          )
           {
-            sbit->width   = (FT_Byte) bitmap->width;
-            sbit->height  = (FT_Byte) bitmap->height;
-            sbit->pitch   = (FT_SChar)bitmap->pitch;
-            sbit->left    = (FT_SChar)slot->bitmap_left;
-            sbit->top     = (FT_SChar)slot->bitmap_top;
-            sbit->advance = (FT_SChar)advance;
+            sbit->width    = (FT_Byte) bitmap->width;
+            sbit->height   = (FT_Byte) bitmap->rows;
+            sbit->pitch    = (FT_Char) bitmap->pitch;
+            sbit->left     = (FT_Char) slot->bitmap_left;
+            sbit->top      = (FT_Char) slot->bitmap_top;
+            sbit->xadvance = (FT_Char) xadvance;
+            sbit->yadvance = (FT_Char) yadvance;
+            sbit->format   = (FT_Byte) bitmap->pixel_mode;
 
             /* grab the bitmap when possible */
             if ( slot->flags & ft_glyph_own_bitmap )
@@ -157,8 +190,6 @@
             }
           }
         }
-        else
-          sbit->buffer = 0;
       }
 
       /* ignore the errors that might have occured there      */
@@ -179,46 +210,33 @@
 
 
   /* this function is important because it is both part of */
-  /* a FTC_ChunkSet_Class and a FTC_CacheNode_Class     */
+  /* a FTC_ChunkSet_Class and a FTC_CacheNode_Class        */
   /*                                                       */
   LOCAL_FUNC_X
-  FT_ULong  ftc_sbit_chunk_node_size( FTC_SBitChunk  node )
+  FT_ULong  ftc_sbit_chunk_node_size( FTC_ChunkNode  node )
   {
-    FT_ULong  size  = 0;
-    FT_Glyph  glyph = node->ft_glyph;
+    FT_ULong      size;
+    FTC_ChunkSet  cset  = node->cset;
+    FT_UInt       count = node->num_elements;
+    FT_Int        pitch;
+    FTC_SBit      sbit  = (FTC_SBit)node->elements;
 
+    size  = sizeof (*node);                            /* the node itself */
+    size += cset->element_count * sizeof(FTC_SBitRec); /* the sbit recors */
 
-    switch ( glyph->format )
+    for ( ; count > 0; count--, sbit++ )
     {
-    case ft_glyph_format_bitmap:
+      if (sbit->buffer)
       {
-        FT_BitmapGlyph  bitg;
-
-
-        bitg = (FT_BitmapGlyph)glyph;
-        size = bitg->bitmap.rows * labs( bitg->bitmap.pitch ) +
-               sizeof ( *bitg );
+        pitch = sbit->pitch;
+        if (pitch < 0)
+          pitch = -pitch;
+          
+        /* add the size of a given glyph image */
+        size += pitch * sbit->height;
       }
-      break;
-
-    case ft_glyph_format_outline:
-      {
-        FT_OutlineGlyph  outg;
-
-
-        outg = (FT_OutlineGlyph)glyph;
-        size = outg->outline.n_points *
-                 ( sizeof( FT_Vector ) + sizeof ( FT_Byte ) ) +
-               outg->outline.n_contours * sizeof ( FT_Short ) +
-               sizeof ( *outg );
-      }
-      break;
-
-    default:
-      ;
     }
 
-    size += sizeof ( *node );
     return size;
   }
 
@@ -226,7 +244,7 @@
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
-  /*****                    GLYPH IMAGE QUEUES                         *****/
+  /*****                     SBIT CHUNK SETS                           *****/
   /*****                                                               *****/
   /*************************************************************************/
   /*************************************************************************/
@@ -233,19 +251,40 @@
 
 
   LOCAL_FUNC_X
-  FT_Error  ftc_image_set_init( FTC_ImageSet     iset,
-                                FTC_Image_Desc*  type )
+  FT_Error  ftc_sbit_chunk_set_sizes( FTC_ChunkSet     cset,
+                                      FTC_Image_Desc*  desc )
   {
-    iset->description = *type;
+    FT_Error  error;
+    FT_Face   face;
+    
+    cset->element_count = FTC_SBITSET_ELEMENT_COUNT;
+    cset->element_size  = sizeof(FTC_SBitRec);
+    
+    /* lookup the FT_Face to obtain the number of glyphs */
+    error = FTC_Manager_Lookup_Face( cset->manager,
+                                     &desc->font, &face );
+    if (!error)
+      cset->element_max = face->num_glyphs;
+      
+    return error;
+  }
+  
+
+
+  LOCAL_FUNC_X
+  FT_Error  ftc_sbit_chunk_set_init( FTC_SBitSet      sset,
+                                     FTC_Image_Desc*  type )
+  {
+    sset->desc = *type;
     return 0;
   }
 
 
   LOCAL_FUNC_X
-  FT_Bool  ftc_image_set_compare( FTC_ImageSet     iset,
-                                  FTC_Image_Desc*  type )
+  FT_Bool  ftc_sbit_chunk_set_compare( FTC_SBitSet      sset,
+                                       FTC_Image_Desc*  type )
   {
-    return !memcmp( &iset->description, type, sizeof ( *type ) );
+    return !memcmp( &sset->desc, type, sizeof ( *type ) );
   }
 
 
@@ -253,13 +292,14 @@
   {
     sizeof( FTC_ImageSetRec ),
 
-    (FTC_ChunkSet_InitFunc)       ftc_image_set_init,
-    (FTC_ChunkSet_DoneFunc)       0,
-    (FTC_ChunkSet_CompareFunc)    ftc_image_set_compare,
+    (FTC_ChunkSet_InitFunc)        ftc_sbit_chunk_set_init,
+    (FTC_ChunkSet_DoneFunc)        0,
+    (FTC_ChunkSet_CompareFunc)     ftc_sbit_chunk_set_compare,
+    (FTC_ChunkSet_SizesFunc)       ftc_sbit_chunk_set_sizes,
 
-    (FTC_ChunkSet_NewNodeFunc)    ftc_sbit_chunk_node_new,
-    (FTC_ChunkSet_SizeNodeFunc)   ftc_sbit_chunk_node_size,
-    (FTC_ChunkSet_DestroyNodeFunc)ftc_sbit_chunk_node_destroy
+    (FTC_ChunkSet_NewNodeFunc)     ftc_sbit_chunk_node_new,
+    (FTC_ChunkSet_SizeNodeFunc)    ftc_sbit_chunk_node_size,
+    (FTC_ChunkSet_DestroyNodeFunc) ftc_sbit_chunk_node_destroy
   };
 
 
@@ -266,66 +306,69 @@
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
-  /*****                    GLYPH IMAGE CACHE                          *****/
+  /*****                     SBITS CACHE                               *****/
   /*****                                                               *****/
   /*************************************************************************/
   /*************************************************************************/
 
 
-  FT_CPLUSPLUS( const FTC_Glyph_Cache_Class )  ftc_sbit_chunk_cache_class =
+  FT_CPLUSPLUS( const FTC_Chunk_Cache_Class )  ftc_sbit_cache_class =
   {
     {
-      sizeof( FTC_Image_CacheRec ),
-      (FTC_Cache_InitFunc) FTC_Glyph_Cache_Init,
-      (FTC_Cache_DoneFunc) FTC_Glyph_Cache_Done
+      sizeof( FTC_SBit_CacheRec ),
+      (FTC_Cache_InitFunc) FTC_Chunk_Cache_Init,
+      (FTC_Cache_DoneFunc) FTC_Chunk_Cache_Done
     },
     (FTC_ChunkSet_Class*) &ftc_sbit_chunk_set_class
   };
 
 
-  FT_EXPORT_FUNC( FT_Error )  FTC_Image_Cache_New( FTC_Manager       manager,
-                                                   FTC_Image_Cache*  acache )
+  FT_EXPORT_FUNC( FT_Error )
+  FTC_SBit_Cache_New( FTC_Manager      manager,
+                      FTC_SBit_Cache*  acache )
   {
     return FTC_Manager_Register_Cache(
               manager,
-              (FTC_Cache_Class*)&ftc_sbit_chunk_cache_class,
+              (FTC_Cache_Class*)&ftc_sbit_cache_class,
               (FTC_Cache*)acache );
   }
 
 
   FT_EXPORT_DEF( FT_Error )
-  FTC_Image_Cache_Lookup( FTC_Image_Cache  cache,
-                          FTC_Image_Desc*  desc,
-                          FT_UInt          gindex,
-                          FT_Glyph*        aglyph )
+  FTC_SBit_Cache_Lookup( FTC_SBit_Cache   cache,
+                         FTC_Image_Desc*  desc,
+                         FT_UInt          gindex,
+                         FTC_SBit        *asbit )
   {
     FT_Error       error;
-    FTC_ChunkSet   gset;
-    FTC_GlyphNode  node;
+    FTC_ChunkSet   cset;
+    FTC_ChunkNode  node;
+    FT_UInt        cindex;
     FTC_Manager    manager;
 
-    FTC_ImageSet   img_set;
+    FTC_SBitSet    sset;
+    FTC_SBit       sbit;
 
 
     /* check for valid `desc' delayed to FT_Lru_Lookup() */
 
-    if ( !cache || !aglyph )
+    if ( !cache || !asbit )
       return FT_Err_Invalid_Argument;
 
-    *aglyph  = 0;
-    gset     = cache->root.last_gset;
-    img_set  = (FTC_ImageSet)gset;
-    if ( !gset || memcmp( &img_set->description, desc, sizeof ( *desc ) ) )
+    *asbit   = 0;
+    cset     = cache->root.last_cset;
+    sset     = (FTC_SBitSet)cset;
+    if ( !cset || memcmp( &sset->desc, desc, sizeof ( *desc ) ) )
     {
-      error = FT_Lru_Lookup( cache->root.gsets_lru,
+      error = FT_Lru_Lookup( cache->root.csets_lru,
                              (FT_LruKey)desc,
-                             (FT_Pointer*)&gset );
-      cache->root.last_gset = gset;
+                             (FT_Pointer*)&cset );
+      cache->root.last_cset = cset;
       if ( error )
         goto Exit;
     }
 
-    error = FTC_ChunkSet_Lookup_Node( gset, gindex, &node );
+    error = FTC_ChunkSet_Lookup_Node( cset, gindex, &node, &cindex );
     if ( error )
       goto Exit;
 
@@ -333,12 +376,19 @@
     manager = cache->root.root.manager;
     if ( manager->num_bytes > manager->max_bytes )
     {
-      FTC_GlyphNode_Ref   ( node );
+      FTC_ChunkNode_Ref   ( node );
       FTC_Manager_Compress( manager );
-      FTC_GlyphNode_Unref ( node );
+      FTC_ChunkNode_Unref ( node );
     }
 
-    *aglyph = ((FTC_SBitChunk)node)->ft_glyph;
+    sbit = ((FTC_SBit)((FTC_ChunkNode)node)->elements) + cindex;
+    if (sbit->buffer == 0)
+    {
+      /* the glyph was missing, we return a NULL pointer !! */
+      sbit = 0;
+    }
+    
+    *asbit = sbit;
 
   Exit:
     return error;
--- a/src/cache/ftcsbits.h
+++ /dev/null
@@ -1,97 +1,0 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftcsbits.h                                                             */
-/*                                                                         */
-/*    a small-bitmaps cache (specification).                               */
-/*                                                                         */
-/*  Copyright 2000 by                                                      */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-#ifndef FTCSBITS_H
-#define FTCSBITS_H
-
-#include <freetype/cache/ftcchunk.h> 
-
-#ifdef __cplusplus
-  extern "C" {
-#endif
-
- /* handle to small bitmap */
-  typedef struct FTC_SBitRec_*   FTC_SBit;
-
-
- /* handle to small bitmap cache */
-  typedef struct FTC_SBit_CacheRec_*   FTC_SBit_Cache;
-
-
- /* format of small bitmaps */  
-  typedef enum FTC_SBit_Format_
-  {
-    ftc_sbit_format_mono  = 0,
-    ftc_sbit_format_aa256 = 1,
-
-  } FTC_SBit_Format;
-
-
- /* a compact structure used to hold a single small bitmap */  
-  typedef struct FTC_SBitRec_
-  {
-    FT_Byte   width;
-    FT_Byte   height;
-    FT_SChar  left;
-    FT_SChar  top;
-
-    FT_Byte   format;
-    FT_SChar  pitch;
-    FT_SChar  xadvance;
-    FT_SChar  yadvance;
-
-    FT_Byte*  buffer;
-  
-  } FTC_SBitRec;
-
-
-  typedef struct FTC_SBitSetRec_
-  {
-    FTC_ChunkSetRec   root;
-    FTC_Image_Desc    desc;
-
-  } FTC_SBitSet;
-
-
-  typedef struct FTC_SBit_CacheRec_
-  {
-    FTC_Chunk_CacheRec    root;
-    
-  } FTC_SBit_CacheRec;
-
-
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_SBit_Cache_New( FTC_Manager      manager,
-                      FTC_SBit_Cache  *acache );
-
-
-  FT_EXPORT_DEF( FT_Error )
-  FTC_SBit_Cache_Lookup( FTC_SBit_Cache   cache,
-                         FTC_Image_Desc*  desc,
-                         FTC_SBit        *sbit );
-
-
-#ifdef __cplusplus
-  }
-#endif
-
-
-#endif /* FTCSBITS_H */
-
-/* END */
-