misc/libfreetype/src/cache/ftcglyph.h
changeset 5172 88f2e05288ba
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libfreetype/src/cache/ftcglyph.h	Mon Apr 25 01:46:54 2011 +0200
@@ -0,0 +1,329 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftcglyph.h                                                             */
+/*                                                                         */
+/*    FreeType abstract glyph cache (specification).                       */
+/*                                                                         */
+/*  Copyright 2000-2001, 2003, 2004, 2006, 2007, 2011 by                   */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*
+   *
+   *  FTC_GCache is an _abstract_ cache object optimized to store glyph
+   *  data.  It works as follows:
+   *
+   *   - It manages FTC_GNode objects. Each one of them can hold one or more
+   *     glyph `items'.  Item types are not specified in the FTC_GCache but
+   *     in classes that extend it.
+   *
+   *   - Glyph attributes, like face ID, character size, render mode, etc.,
+   *     can be grouped into abstract `glyph families'.  This avoids storing
+   *     the attributes within the FTC_GCache, since it is likely that many
+   *     FTC_GNodes will belong to the same family in typical uses.
+   *
+   *   - Each FTC_GNode is thus an FTC_Node with two additional fields:
+   *
+   *       * gindex: A glyph index, or the first index in a glyph range.
+   *       * family: A pointer to a glyph `family'.
+   *
+   *   - Family types are not fully specific in the FTC_Family type, but
+   *     by classes that extend it.
+   *
+   *  Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache.
+   *  They share an FTC_Family sub-class called FTC_BasicFamily which is
+   *  used to store the following data: face ID, pixel/point sizes, load
+   *  flags.  For more details see the file `src/cache/ftcbasic.c'.
+   *
+   *  Client applications can extend FTC_GNode with their own FTC_GNode
+   *  and FTC_Family sub-classes to implement more complex caches (e.g.,
+   *  handling automatic synthesis, like obliquing & emboldening, colored
+   *  glyphs, etc.).
+   *
+   *  See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and
+   *  `ftcsbits.h', which both extend FTC_GCache with additional
+   *  optimizations.
+   *
+   *  A typical FTC_GCache implementation must provide at least the
+   *  following:
+   *
+   *  - FTC_GNode sub-class, e.g. MyNode, with relevant methods:
+   *        my_node_new            (must call FTC_GNode_Init)
+   *        my_node_free           (must call FTC_GNode_Done)
+   *        my_node_compare        (must call FTC_GNode_Compare)
+   *        my_node_remove_faceid  (must call ftc_gnode_unselect in case
+   *                                of match)
+   *
+   *  - FTC_Family sub-class, e.g. MyFamily, with relevant methods:
+   *        my_family_compare
+   *        my_family_init
+   *        my_family_reset (optional)
+   *        my_family_done
+   *
+   *  - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query
+   *    data.
+   *
+   *  - Constant structures for a FTC_GNodeClass.
+   *
+   *  - MyCacheNew() can be implemented easily as a call to the convenience
+   *    function FTC_GCache_New.
+   *
+   *  - MyCacheLookup with a call to FTC_GCache_Lookup.  This function will
+   *    automatically:
+   *
+   *    - Search for the corresponding family in the cache, or create
+   *      a new one if necessary.  Put it in FTC_GQUERY(myquery).family
+   *
+   *    - Call FTC_Cache_Lookup.
+   *
+   *    If it returns NULL, you should create a new node, then call
+   *    ftc_cache_add as usual.
+   */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Important: The functions defined in this file are only used to        */
+  /*            implement an abstract glyph cache class.  You need to      */
+  /*            provide additional logic to implement a complete cache.    */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*********                                                       *********/
+  /*********             WARNING, THIS IS BETA CODE.               *********/
+  /*********                                                       *********/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+#ifndef __FTCGLYPH_H__
+#define __FTCGLYPH_H__
+
+
+#include <ft2build.h>
+#include "ftcmanag.h"
+
+
+FT_BEGIN_HEADER
+
+
+ /*
+  *  We can group glyphs into `families'.  Each family correspond to a
+  *  given face ID, character size, transform, etc.
+  *
+  *  Families are implemented as MRU list nodes.  They are
+  *  reference-counted.
+  */
+
+  typedef struct  FTC_FamilyRec_
+  {
+    FTC_MruNodeRec    mrunode;
+    FT_UInt           num_nodes; /* current number of nodes in this family */
+    FTC_Cache         cache;
+    FTC_MruListClass  clazz;
+
+  } FTC_FamilyRec, *FTC_Family;
+
+#define  FTC_FAMILY(x)    ( (FTC_Family)(x) )
+#define  FTC_FAMILY_P(x)  ( (FTC_Family*)(x) )
+
+
+  typedef struct  FTC_GNodeRec_
+  {
+    FTC_NodeRec      node;
+    FTC_Family       family;
+    FT_UInt          gindex;
+
+  } FTC_GNodeRec, *FTC_GNode;
+
+#define FTC_GNODE( x )    ( (FTC_GNode)(x) )
+#define FTC_GNODE_P( x )  ( (FTC_GNode*)(x) )
+
+
+  typedef struct  FTC_GQueryRec_
+  {
+    FT_UInt      gindex;
+    FTC_Family   family;
+
+  } FTC_GQueryRec, *FTC_GQuery;
+
+#define FTC_GQUERY( x )  ( (FTC_GQuery)(x) )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* These functions are exported so that they can be called from          */
+  /* user-provided cache classes; otherwise, they are really part of the   */
+  /* cache sub-system internals.                                           */
+  /*                                                                       */
+
+  /* must be called by derived FTC_Node_InitFunc routines */
+  FT_LOCAL( void )
+  FTC_GNode_Init( FTC_GNode   node,
+                  FT_UInt     gindex,  /* glyph index for node */
+                  FTC_Family  family );
+
+#ifdef FTC_INLINE
+
+  /* returns TRUE iff the query's glyph index correspond to the node;  */
+  /* this assumes that the `family' and `hash' fields of the query are */
+  /* already correctly set                                             */
+  FT_LOCAL( FT_Bool )
+  FTC_GNode_Compare( FTC_GNode   gnode,
+                     FTC_GQuery  gquery,
+                     FTC_Cache   cache,
+                     FT_Bool*    list_changed );
+
+#endif
+
+  /* call this function to clear a node's family -- this is necessary */
+  /* to implement the `node_remove_faceid' cache method correctly     */
+  FT_LOCAL( void )
+  FTC_GNode_UnselectFamily( FTC_GNode  gnode,
+                            FTC_Cache  cache );
+
+  /* must be called by derived FTC_Node_DoneFunc routines */
+  FT_LOCAL( void )
+  FTC_GNode_Done( FTC_GNode  node,
+                  FTC_Cache  cache );
+
+
+  FT_LOCAL( void )
+  FTC_Family_Init( FTC_Family  family,
+                   FTC_Cache   cache );
+
+  typedef struct FTC_GCacheRec_
+  {
+    FTC_CacheRec    cache;
+    FTC_MruListRec  families;
+
+  } FTC_GCacheRec, *FTC_GCache;
+
+#define FTC_GCACHE( x )  ((FTC_GCache)(x))
+
+
+#if 0
+  /* can be used as @FTC_Cache_InitFunc */
+  FT_LOCAL( FT_Error )
+  FTC_GCache_Init( FTC_GCache  cache );
+#endif
+
+
+#if 0
+  /* can be used as @FTC_Cache_DoneFunc */
+  FT_LOCAL( void )
+  FTC_GCache_Done( FTC_GCache  cache );
+#endif
+
+
+  /* the glyph cache class adds fields for the family implementation */
+  typedef struct  FTC_GCacheClassRec_
+  {
+    FTC_CacheClassRec  clazz;
+    FTC_MruListClass   family_class;
+
+  } FTC_GCacheClassRec;
+
+  typedef const FTC_GCacheClassRec*   FTC_GCacheClass;
+
+#define FTC_GCACHE_CLASS( x )  ((FTC_GCacheClass)(x))
+
+#define FTC_CACHE__GCACHE_CLASS( x ) \
+          FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class )
+#define FTC_CACHE__FAMILY_CLASS( x ) \
+          ( (FTC_MruListClass)FTC_CACHE__GCACHE_CLASS( x )->family_class )
+
+
+  /* convenience function; use it instead of FTC_Manager_Register_Cache */
+  FT_LOCAL( FT_Error )
+  FTC_GCache_New( FTC_Manager       manager,
+                  FTC_GCacheClass   clazz,
+                  FTC_GCache       *acache );
+
+#ifndef FTC_INLINE
+  FT_LOCAL( FT_Error )
+  FTC_GCache_Lookup( FTC_GCache   cache,
+                     FT_PtrDist   hash,
+                     FT_UInt      gindex,
+                     FTC_GQuery   query,
+                     FTC_Node    *anode );
+#endif
+
+
+  /* */
+
+
+#define FTC_FAMILY_FREE( family, cache )                      \
+          FTC_MruList_Remove( &FTC_GCACHE((cache))->families, \
+                              (FTC_MruNode)(family) )
+
+
+#ifdef FTC_INLINE
+
+#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash,                \
+                               gindex, query, node, error )                 \
+  FT_BEGIN_STMNT                                                            \
+    FTC_GCache               _gcache   = FTC_GCACHE( cache );               \
+    FTC_GQuery               _gquery   = (FTC_GQuery)( query );             \
+    FTC_MruNode_CompareFunc  _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \
+    FTC_MruNode              _mrunode;                                      \
+                                                                            \
+                                                                            \
+    _gquery->gindex = (gindex);                                             \
+                                                                            \
+    FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare,         \
+                            _mrunode, error );                              \
+    _gquery->family = FTC_FAMILY( _mrunode );                               \
+    if ( !error )                                                           \
+    {                                                                       \
+      FTC_Family  _gqfamily = _gquery->family;                              \
+                                                                            \
+                                                                            \
+      _gqfamily->num_nodes++;                                               \
+                                                                            \
+      FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error );     \
+                                                                            \
+      if ( --_gqfamily->num_nodes == 0 )                                    \
+        FTC_FAMILY_FREE( _gqfamily, _gcache );                              \
+    }                                                                       \
+  FT_END_STMNT
+  /* */
+
+#else /* !FTC_INLINE */
+
+#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash,          \
+                               gindex, query, node, error )           \
+   FT_BEGIN_STMNT                                                     \
+                                                                      \
+     error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex,    \
+                                FTC_GQUERY( query ), &node );         \
+                                                                      \
+   FT_END_STMNT
+
+#endif /* !FTC_INLINE */
+
+
+FT_END_HEADER
+
+
+#endif /* __FTCGLYPH_H__ */
+
+
+/* END */