misc/libfreetype/src/cache/ftcglyph.h
changeset 5172 88f2e05288ba
equal deleted inserted replaced
5171:f9283dc4860d 5172:88f2e05288ba
       
     1 /***************************************************************************/
       
     2 /*                                                                         */
       
     3 /*  ftcglyph.h                                                             */
       
     4 /*                                                                         */
       
     5 /*    FreeType abstract glyph cache (specification).                       */
       
     6 /*                                                                         */
       
     7 /*  Copyright 2000-2001, 2003, 2004, 2006, 2007, 2011 by                   */
       
     8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
       
     9 /*                                                                         */
       
    10 /*  This file is part of the FreeType project, and may only be used,       */
       
    11 /*  modified, and distributed under the terms of the FreeType project      */
       
    12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
       
    13 /*  this file you indicate that you have read the license and              */
       
    14 /*  understand and accept it fully.                                        */
       
    15 /*                                                                         */
       
    16 /***************************************************************************/
       
    17 
       
    18 
       
    19   /*
       
    20    *
       
    21    *  FTC_GCache is an _abstract_ cache object optimized to store glyph
       
    22    *  data.  It works as follows:
       
    23    *
       
    24    *   - It manages FTC_GNode objects. Each one of them can hold one or more
       
    25    *     glyph `items'.  Item types are not specified in the FTC_GCache but
       
    26    *     in classes that extend it.
       
    27    *
       
    28    *   - Glyph attributes, like face ID, character size, render mode, etc.,
       
    29    *     can be grouped into abstract `glyph families'.  This avoids storing
       
    30    *     the attributes within the FTC_GCache, since it is likely that many
       
    31    *     FTC_GNodes will belong to the same family in typical uses.
       
    32    *
       
    33    *   - Each FTC_GNode is thus an FTC_Node with two additional fields:
       
    34    *
       
    35    *       * gindex: A glyph index, or the first index in a glyph range.
       
    36    *       * family: A pointer to a glyph `family'.
       
    37    *
       
    38    *   - Family types are not fully specific in the FTC_Family type, but
       
    39    *     by classes that extend it.
       
    40    *
       
    41    *  Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache.
       
    42    *  They share an FTC_Family sub-class called FTC_BasicFamily which is
       
    43    *  used to store the following data: face ID, pixel/point sizes, load
       
    44    *  flags.  For more details see the file `src/cache/ftcbasic.c'.
       
    45    *
       
    46    *  Client applications can extend FTC_GNode with their own FTC_GNode
       
    47    *  and FTC_Family sub-classes to implement more complex caches (e.g.,
       
    48    *  handling automatic synthesis, like obliquing & emboldening, colored
       
    49    *  glyphs, etc.).
       
    50    *
       
    51    *  See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and
       
    52    *  `ftcsbits.h', which both extend FTC_GCache with additional
       
    53    *  optimizations.
       
    54    *
       
    55    *  A typical FTC_GCache implementation must provide at least the
       
    56    *  following:
       
    57    *
       
    58    *  - FTC_GNode sub-class, e.g. MyNode, with relevant methods:
       
    59    *        my_node_new            (must call FTC_GNode_Init)
       
    60    *        my_node_free           (must call FTC_GNode_Done)
       
    61    *        my_node_compare        (must call FTC_GNode_Compare)
       
    62    *        my_node_remove_faceid  (must call ftc_gnode_unselect in case
       
    63    *                                of match)
       
    64    *
       
    65    *  - FTC_Family sub-class, e.g. MyFamily, with relevant methods:
       
    66    *        my_family_compare
       
    67    *        my_family_init
       
    68    *        my_family_reset (optional)
       
    69    *        my_family_done
       
    70    *
       
    71    *  - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query
       
    72    *    data.
       
    73    *
       
    74    *  - Constant structures for a FTC_GNodeClass.
       
    75    *
       
    76    *  - MyCacheNew() can be implemented easily as a call to the convenience
       
    77    *    function FTC_GCache_New.
       
    78    *
       
    79    *  - MyCacheLookup with a call to FTC_GCache_Lookup.  This function will
       
    80    *    automatically:
       
    81    *
       
    82    *    - Search for the corresponding family in the cache, or create
       
    83    *      a new one if necessary.  Put it in FTC_GQUERY(myquery).family
       
    84    *
       
    85    *    - Call FTC_Cache_Lookup.
       
    86    *
       
    87    *    If it returns NULL, you should create a new node, then call
       
    88    *    ftc_cache_add as usual.
       
    89    */
       
    90 
       
    91 
       
    92   /*************************************************************************/
       
    93   /*                                                                       */
       
    94   /* Important: The functions defined in this file are only used to        */
       
    95   /*            implement an abstract glyph cache class.  You need to      */
       
    96   /*            provide additional logic to implement a complete cache.    */
       
    97   /*                                                                       */
       
    98   /*************************************************************************/
       
    99 
       
   100 
       
   101   /*************************************************************************/
       
   102   /*************************************************************************/
       
   103   /*************************************************************************/
       
   104   /*************************************************************************/
       
   105   /*************************************************************************/
       
   106   /*********                                                       *********/
       
   107   /*********             WARNING, THIS IS BETA CODE.               *********/
       
   108   /*********                                                       *********/
       
   109   /*************************************************************************/
       
   110   /*************************************************************************/
       
   111   /*************************************************************************/
       
   112   /*************************************************************************/
       
   113   /*************************************************************************/
       
   114 
       
   115 
       
   116 #ifndef __FTCGLYPH_H__
       
   117 #define __FTCGLYPH_H__
       
   118 
       
   119 
       
   120 #include <ft2build.h>
       
   121 #include "ftcmanag.h"
       
   122 
       
   123 
       
   124 FT_BEGIN_HEADER
       
   125 
       
   126 
       
   127  /*
       
   128   *  We can group glyphs into `families'.  Each family correspond to a
       
   129   *  given face ID, character size, transform, etc.
       
   130   *
       
   131   *  Families are implemented as MRU list nodes.  They are
       
   132   *  reference-counted.
       
   133   */
       
   134 
       
   135   typedef struct  FTC_FamilyRec_
       
   136   {
       
   137     FTC_MruNodeRec    mrunode;
       
   138     FT_UInt           num_nodes; /* current number of nodes in this family */
       
   139     FTC_Cache         cache;
       
   140     FTC_MruListClass  clazz;
       
   141 
       
   142   } FTC_FamilyRec, *FTC_Family;
       
   143 
       
   144 #define  FTC_FAMILY(x)    ( (FTC_Family)(x) )
       
   145 #define  FTC_FAMILY_P(x)  ( (FTC_Family*)(x) )
       
   146 
       
   147 
       
   148   typedef struct  FTC_GNodeRec_
       
   149   {
       
   150     FTC_NodeRec      node;
       
   151     FTC_Family       family;
       
   152     FT_UInt          gindex;
       
   153 
       
   154   } FTC_GNodeRec, *FTC_GNode;
       
   155 
       
   156 #define FTC_GNODE( x )    ( (FTC_GNode)(x) )
       
   157 #define FTC_GNODE_P( x )  ( (FTC_GNode*)(x) )
       
   158 
       
   159 
       
   160   typedef struct  FTC_GQueryRec_
       
   161   {
       
   162     FT_UInt      gindex;
       
   163     FTC_Family   family;
       
   164 
       
   165   } FTC_GQueryRec, *FTC_GQuery;
       
   166 
       
   167 #define FTC_GQUERY( x )  ( (FTC_GQuery)(x) )
       
   168 
       
   169 
       
   170   /*************************************************************************/
       
   171   /*                                                                       */
       
   172   /* These functions are exported so that they can be called from          */
       
   173   /* user-provided cache classes; otherwise, they are really part of the   */
       
   174   /* cache sub-system internals.                                           */
       
   175   /*                                                                       */
       
   176 
       
   177   /* must be called by derived FTC_Node_InitFunc routines */
       
   178   FT_LOCAL( void )
       
   179   FTC_GNode_Init( FTC_GNode   node,
       
   180                   FT_UInt     gindex,  /* glyph index for node */
       
   181                   FTC_Family  family );
       
   182 
       
   183 #ifdef FTC_INLINE
       
   184 
       
   185   /* returns TRUE iff the query's glyph index correspond to the node;  */
       
   186   /* this assumes that the `family' and `hash' fields of the query are */
       
   187   /* already correctly set                                             */
       
   188   FT_LOCAL( FT_Bool )
       
   189   FTC_GNode_Compare( FTC_GNode   gnode,
       
   190                      FTC_GQuery  gquery,
       
   191                      FTC_Cache   cache,
       
   192                      FT_Bool*    list_changed );
       
   193 
       
   194 #endif
       
   195 
       
   196   /* call this function to clear a node's family -- this is necessary */
       
   197   /* to implement the `node_remove_faceid' cache method correctly     */
       
   198   FT_LOCAL( void )
       
   199   FTC_GNode_UnselectFamily( FTC_GNode  gnode,
       
   200                             FTC_Cache  cache );
       
   201 
       
   202   /* must be called by derived FTC_Node_DoneFunc routines */
       
   203   FT_LOCAL( void )
       
   204   FTC_GNode_Done( FTC_GNode  node,
       
   205                   FTC_Cache  cache );
       
   206 
       
   207 
       
   208   FT_LOCAL( void )
       
   209   FTC_Family_Init( FTC_Family  family,
       
   210                    FTC_Cache   cache );
       
   211 
       
   212   typedef struct FTC_GCacheRec_
       
   213   {
       
   214     FTC_CacheRec    cache;
       
   215     FTC_MruListRec  families;
       
   216 
       
   217   } FTC_GCacheRec, *FTC_GCache;
       
   218 
       
   219 #define FTC_GCACHE( x )  ((FTC_GCache)(x))
       
   220 
       
   221 
       
   222 #if 0
       
   223   /* can be used as @FTC_Cache_InitFunc */
       
   224   FT_LOCAL( FT_Error )
       
   225   FTC_GCache_Init( FTC_GCache  cache );
       
   226 #endif
       
   227 
       
   228 
       
   229 #if 0
       
   230   /* can be used as @FTC_Cache_DoneFunc */
       
   231   FT_LOCAL( void )
       
   232   FTC_GCache_Done( FTC_GCache  cache );
       
   233 #endif
       
   234 
       
   235 
       
   236   /* the glyph cache class adds fields for the family implementation */
       
   237   typedef struct  FTC_GCacheClassRec_
       
   238   {
       
   239     FTC_CacheClassRec  clazz;
       
   240     FTC_MruListClass   family_class;
       
   241 
       
   242   } FTC_GCacheClassRec;
       
   243 
       
   244   typedef const FTC_GCacheClassRec*   FTC_GCacheClass;
       
   245 
       
   246 #define FTC_GCACHE_CLASS( x )  ((FTC_GCacheClass)(x))
       
   247 
       
   248 #define FTC_CACHE__GCACHE_CLASS( x ) \
       
   249           FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class )
       
   250 #define FTC_CACHE__FAMILY_CLASS( x ) \
       
   251           ( (FTC_MruListClass)FTC_CACHE__GCACHE_CLASS( x )->family_class )
       
   252 
       
   253 
       
   254   /* convenience function; use it instead of FTC_Manager_Register_Cache */
       
   255   FT_LOCAL( FT_Error )
       
   256   FTC_GCache_New( FTC_Manager       manager,
       
   257                   FTC_GCacheClass   clazz,
       
   258                   FTC_GCache       *acache );
       
   259 
       
   260 #ifndef FTC_INLINE
       
   261   FT_LOCAL( FT_Error )
       
   262   FTC_GCache_Lookup( FTC_GCache   cache,
       
   263                      FT_PtrDist   hash,
       
   264                      FT_UInt      gindex,
       
   265                      FTC_GQuery   query,
       
   266                      FTC_Node    *anode );
       
   267 #endif
       
   268 
       
   269 
       
   270   /* */
       
   271 
       
   272 
       
   273 #define FTC_FAMILY_FREE( family, cache )                      \
       
   274           FTC_MruList_Remove( &FTC_GCACHE((cache))->families, \
       
   275                               (FTC_MruNode)(family) )
       
   276 
       
   277 
       
   278 #ifdef FTC_INLINE
       
   279 
       
   280 #define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash,                \
       
   281                                gindex, query, node, error )                 \
       
   282   FT_BEGIN_STMNT                                                            \
       
   283     FTC_GCache               _gcache   = FTC_GCACHE( cache );               \
       
   284     FTC_GQuery               _gquery   = (FTC_GQuery)( query );             \
       
   285     FTC_MruNode_CompareFunc  _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \
       
   286     FTC_MruNode              _mrunode;                                      \
       
   287                                                                             \
       
   288                                                                             \
       
   289     _gquery->gindex = (gindex);                                             \
       
   290                                                                             \
       
   291     FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare,         \
       
   292                             _mrunode, error );                              \
       
   293     _gquery->family = FTC_FAMILY( _mrunode );                               \
       
   294     if ( !error )                                                           \
       
   295     {                                                                       \
       
   296       FTC_Family  _gqfamily = _gquery->family;                              \
       
   297                                                                             \
       
   298                                                                             \
       
   299       _gqfamily->num_nodes++;                                               \
       
   300                                                                             \
       
   301       FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error );     \
       
   302                                                                             \
       
   303       if ( --_gqfamily->num_nodes == 0 )                                    \
       
   304         FTC_FAMILY_FREE( _gqfamily, _gcache );                              \
       
   305     }                                                                       \
       
   306   FT_END_STMNT
       
   307   /* */
       
   308 
       
   309 #else /* !FTC_INLINE */
       
   310 
       
   311 #define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash,          \
       
   312                                gindex, query, node, error )           \
       
   313    FT_BEGIN_STMNT                                                     \
       
   314                                                                       \
       
   315      error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex,    \
       
   316                                 FTC_GQUERY( query ), &node );         \
       
   317                                                                       \
       
   318    FT_END_STMNT
       
   319 
       
   320 #endif /* !FTC_INLINE */
       
   321 
       
   322 
       
   323 FT_END_HEADER
       
   324 
       
   325 
       
   326 #endif /* __FTCGLYPH_H__ */
       
   327 
       
   328 
       
   329 /* END */