source: trunk/poppler/freetype-2.1.10/include/freetype/cache/ftccache.h @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 15 years ago

First import

File size: 13.9 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  ftccache.h                                                             */
4/*                                                                         */
5/*    FreeType internal cache interface (specification).                   */
6/*                                                                         */
7/*  Copyright 2000-2001, 2002, 2003, 2004, 2005 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#ifndef __FTCCACHE_H__
20#define __FTCCACHE_H__
21
22
23#include FT_CACHE_INTERNAL_MRU_H
24
25FT_BEGIN_HEADER
26
27  /* handle to cache object */
28  typedef struct FTC_CacheRec_*  FTC_Cache;
29
30  /* handle to cache class */
31  typedef const struct FTC_CacheClassRec_*  FTC_CacheClass;
32
33
34  /*************************************************************************/
35  /*************************************************************************/
36  /*****                                                               *****/
37  /*****                   CACHE NODE DEFINITIONS                      *****/
38  /*****                                                               *****/
39  /*************************************************************************/
40  /*************************************************************************/
41
42  /*************************************************************************/
43  /*                                                                       */
44  /* Each cache controls one or more cache nodes.  Each node is part of    */
45  /* the global_lru list of the manager.  Its `data' field however is used */
46  /* as a reference count for now.                                         */
47  /*                                                                       */
48  /* A node can be anything, depending on the type of information held by  */
49  /* the cache.  It can be an individual glyph image, a set of bitmaps     */
50  /* glyphs for a given size, some metrics, etc.                           */
51  /*                                                                       */
52  /*************************************************************************/
53
54  /* structure size should be 20 bytes on 32-bits machines */
55  typedef struct  FTC_NodeRec_
56  {
57    FTC_MruNodeRec  mru;          /* circular mru list pointer           */
58    FTC_Node        link;         /* used for hashing                    */
59    FT_UInt32       hash;         /* used for hashing too                */
60    FT_UShort       cache_index;  /* index of cache the node belongs to  */
61    FT_Short        ref_count;    /* reference count for this node       */
62
63  } FTC_NodeRec;
64
65
66#define FTC_NODE( x )    ( (FTC_Node)(x) )
67#define FTC_NODE_P( x )  ( (FTC_Node*)(x) )
68
69#define FTC_NODE__NEXT(x)  FTC_NODE( (x)->mru.next )
70#define FTC_NODE__PREV(x)  FTC_NODE( (x)->mru.prev )
71
72
73  /*************************************************************************/
74  /*                                                                       */
75  /* These functions are exported so that they can be called from          */
76  /* user-provided cache classes; otherwise, they are really part of the   */
77  /* cache sub-system internals.                                           */
78  /*                                                                       */
79
80  /* reserved for manager's use */
81  FT_EXPORT( void )
82  ftc_node_destroy( FTC_Node     node,
83                    FTC_Manager  manager );
84
85
86  /*************************************************************************/
87  /*************************************************************************/
88  /*****                                                               *****/
89  /*****                       CACHE DEFINITIONS                       *****/
90  /*****                                                               *****/
91  /*************************************************************************/
92  /*************************************************************************/
93
94  /* initialize a new cache node */
95  typedef FT_Error
96  (*FTC_Node_NewFunc)( FTC_Node    *pnode,
97                       FT_Pointer   query,
98                       FTC_Cache    cache );
99
100  typedef FT_ULong
101  (*FTC_Node_WeightFunc)( FTC_Node   node,
102                          FTC_Cache  cache );
103
104  /* compare a node to a given key pair */
105  typedef FT_Bool
106  (*FTC_Node_CompareFunc)( FTC_Node    node,
107                           FT_Pointer  key,
108                           FTC_Cache   cache );
109
110
111  typedef void
112  (*FTC_Node_FreeFunc)( FTC_Node   node,
113                        FTC_Cache  cache );
114
115  typedef FT_Error
116  (*FTC_Cache_InitFunc)( FTC_Cache  cache );
117
118  typedef void
119  (*FTC_Cache_DoneFunc)( FTC_Cache  cache );
120
121
122  typedef struct  FTC_CacheClassRec_
123  {
124    FTC_Node_NewFunc      node_new;
125    FTC_Node_WeightFunc   node_weight;
126    FTC_Node_CompareFunc  node_compare;
127    FTC_Node_CompareFunc  node_remove_faceid;
128    FTC_Node_FreeFunc     node_free;
129
130    FT_UInt               cache_size;
131    FTC_Cache_InitFunc    cache_init;
132    FTC_Cache_DoneFunc    cache_done;
133
134  } FTC_CacheClassRec;
135
136
137  /* each cache really implements a dynamic hash table to manage its nodes */
138  typedef struct  FTC_CacheRec_
139  {
140    FT_UFast           p;
141    FT_UFast           mask;
142    FT_Long            slack;
143    FTC_Node*          buckets;
144
145    FTC_CacheClassRec  clazz;       /* local copy, for speed  */
146
147    FTC_Manager        manager;
148    FT_Memory          memory;
149    FT_UInt            index;       /* in manager's table     */
150
151    FTC_CacheClass     org_class;   /* original class pointer */
152
153  } FTC_CacheRec;
154
155
156#define FTC_CACHE( x )    ( (FTC_Cache)(x) )
157#define FTC_CACHE_P( x )  ( (FTC_Cache*)(x) )
158
159
160  /* default cache initialize */
161  FT_EXPORT( FT_Error )
162  FTC_Cache_Init( FTC_Cache  cache );
163
164  /* default cache finalizer */
165  FT_EXPORT( void )
166  FTC_Cache_Done( FTC_Cache  cache );
167
168  /* Call this function to lookup the cache.  If no corresponding
169   * node is found, a new one is automatically created.  This function
170   * is capable of flushing the cache adequately to make room for the
171   * new cache object.
172   */
173  FT_EXPORT( FT_Error )
174  FTC_Cache_Lookup( FTC_Cache   cache,
175                    FT_UInt32   hash,
176                    FT_Pointer  query,
177                    FTC_Node   *anode );
178
179  FT_EXPORT( FT_Error )
180  FTC_Cache_NewNode( FTC_Cache   cache,
181                     FT_UInt32   hash,
182                     FT_Pointer  query,
183                     FTC_Node   *anode );
184
185  /* Remove all nodes that relate to a given face_id.  This is useful
186   * when un-installing fonts.  Note that if a cache node relates to
187   * the face_id, but is locked (i.e., has 'ref_count > 0'), the node
188   * will _not_ be destroyed, but its internal face_id reference will
189   * be modified.
190   *
191   * The final result will be that the node will never come back
192   * in further lookup requests, and will be flushed on demand from
193   * the cache normally when its reference count reaches 0.
194   */
195  FT_EXPORT( void )
196  FTC_Cache_RemoveFaceID( FTC_Cache   cache,
197                          FTC_FaceID  face_id );
198
199
200#ifdef FTC_INLINE
201
202#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \
203  FT_BEGIN_STMNT                                                         \
204    FTC_Node             *_bucket, *_pnode, _node;                       \
205    FTC_Cache             _cache   = FTC_CACHE(cache);                   \
206    FT_UInt32             _hash    = (FT_UInt32)(hash);                  \
207    FTC_Node_CompareFunc  _nodcomp = (FTC_Node_CompareFunc)(nodecmp);    \
208    FT_UInt               _idx;                                          \
209                                                                         \
210                                                                         \
211    error = 0;                                                           \
212    node  = NULL;                                                        \
213    _idx  = _hash & _cache->mask;                                        \
214    if ( _idx < _cache->p )                                              \
215      _idx = _hash & ( _cache->mask*2 + 1 );                             \
216                                                                         \
217    _bucket = _pnode = _cache->buckets + _idx;                           \
218    for (;;)                                                             \
219    {                                                                    \
220      _node = *_pnode;                                                   \
221      if ( _node == NULL )                                               \
222        goto _NewNode;                                                   \
223                                                                         \
224      if ( _node->hash == _hash && _nodcomp( _node, query, _cache ) )    \
225        break;                                                           \
226                                                                         \
227      _pnode = &_node->link;                                             \
228    }                                                                    \
229                                                                         \
230    if ( _node != *_bucket )                                             \
231    {                                                                    \
232      *_pnode     = _node->link;                                         \
233      _node->link = *_bucket;                                            \
234      *_bucket    = _node;                                               \
235    }                                                                    \
236                                                                         \
237    {                                                                    \
238      FTC_Manager  _manager = _cache->manager;                           \
239                                                                         \
240                                                                         \
241      if ( _node != _manager->nodes_list )                               \
242        FTC_MruNode_Up( (FTC_MruNode*)&_manager->nodes_list,             \
243                        (FTC_MruNode)_node );                            \
244    }                                                                    \
245    goto _Ok;                                                            \
246                                                                         \
247  _NewNode:                                                              \
248    error = FTC_Cache_NewNode( _cache, _hash, query, &_node );           \
249                                                                         \
250  _Ok:                                                                   \
251    _pnode = (FTC_Node*)(void*)&(node);                                  \
252    *_pnode = _node;                                                     \
253  FT_END_STMNT
254
255#else /* !FTC_INLINE */
256
257#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \
258  FT_BEGIN_STMNT                                                         \
259    error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query,           \
260                              (FTC_Node*)&(node) );                      \
261  FT_END_STMNT
262
263#endif /* !FTC_INLINE */
264
265
266  /*
267   * This macro, together with FTC_CACHE_TRYLOOP_END, defines a retry
268   * loop to flush the cache repeatedly in case of memory overflows.
269   *
270   * It is used when creating a new cache node, or within a lookup
271   * that needs to allocate data (e.g., the sbit cache lookup).
272   *
273   * Example:
274   *
275   *   {
276   *     FTC_CACHE_TRYLOOP( cache )
277   *       error = load_data( ... );
278   *     FTC_CACHE_TRYLOOP_END()
279   *   }
280   *
281   */
282#define FTC_CACHE_TRYLOOP( cache )                           \
283  {                                                          \
284    FTC_Manager  _try_manager = FTC_CACHE( cache )->manager; \
285    FT_UInt      _try_count   = 4;                           \
286                                                             \
287                                                             \
288    for (;;)                                                 \
289    {                                                        \
290      FT_UInt  _try_done;
291
292
293#define FTC_CACHE_TRYLOOP_END()                                   \
294      if ( !error || error != FT_Err_Out_Of_Memory )              \
295        break;                                                    \
296                                                                  \
297      _try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \
298      if ( _try_done == 0 )                                       \
299        break;                                                    \
300                                                                  \
301      if ( _try_done == _try_count )                              \
302      {                                                           \
303        _try_count *= 2;                                          \
304        if ( _try_count < _try_done              ||               \
305            _try_count > _try_manager->num_nodes )                \
306          _try_count = _try_manager->num_nodes;                   \
307      }                                                           \
308    }                                                             \
309  }
310
311 /* */
312
313FT_END_HEADER
314
315
316#endif /* __FTCCACHE_H__ */
317
318
319/* END */
Note: See TracBrowser for help on using the repository browser.