Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenftccache.h
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* ftccache.h */ 00004 /* */ 00005 /* FreeType internal cache interface (specification). */ 00006 /* */ 00007 /* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */ 00008 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 00009 /* */ 00010 /* This file is part of the FreeType project, and may only be used, */ 00011 /* modified, and distributed under the terms of the FreeType project */ 00012 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 00013 /* this file you indicate that you have read the license and */ 00014 /* understand and accept it fully. */ 00015 /* */ 00016 /***************************************************************************/ 00017 00018 00019 #ifndef __FTCCACHE_H__ 00020 #define __FTCCACHE_H__ 00021 00022 00023 #include "ftcmru.h" 00024 00025 FT_BEGIN_HEADER 00026 00027 #define _FTC_FACE_ID_HASH( i ) \ 00028 ((FT_PtrDist)(( (FT_PtrDist)(i) >> 3 ) ^ ( (FT_PtrDist)(i) << 7 ))) 00029 00030 /* handle to cache object */ 00031 typedef struct FTC_CacheRec_* FTC_Cache; 00032 00033 /* handle to cache class */ 00034 typedef const struct FTC_CacheClassRec_* FTC_CacheClass; 00035 00036 00037 /*************************************************************************/ 00038 /*************************************************************************/ 00039 /***** *****/ 00040 /***** CACHE NODE DEFINITIONS *****/ 00041 /***** *****/ 00042 /*************************************************************************/ 00043 /*************************************************************************/ 00044 00045 /*************************************************************************/ 00046 /* */ 00047 /* Each cache controls one or more cache nodes. Each node is part of */ 00048 /* the global_lru list of the manager. Its `data' field however is used */ 00049 /* as a reference count for now. */ 00050 /* */ 00051 /* A node can be anything, depending on the type of information held by */ 00052 /* the cache. It can be an individual glyph image, a set of bitmaps */ 00053 /* glyphs for a given size, some metrics, etc. */ 00054 /* */ 00055 /*************************************************************************/ 00056 00057 /* structure size should be 20 bytes on 32-bits machines */ 00058 typedef struct FTC_NodeRec_ 00059 { 00060 FTC_MruNodeRec mru; /* circular mru list pointer */ 00061 FTC_Node link; /* used for hashing */ 00062 FT_PtrDist hash; /* used for hashing too */ 00063 FT_UShort cache_index; /* index of cache the node belongs to */ 00064 FT_Short ref_count; /* reference count for this node */ 00065 00066 } FTC_NodeRec; 00067 00068 00069 #define FTC_NODE( x ) ( (FTC_Node)(x) ) 00070 #define FTC_NODE_P( x ) ( (FTC_Node*)(x) ) 00071 00072 #define FTC_NODE__NEXT( x ) FTC_NODE( (x)->mru.next ) 00073 #define FTC_NODE__PREV( x ) FTC_NODE( (x)->mru.prev ) 00074 00075 00076 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS 00077 FT_BASE( void ) 00078 ftc_node_destroy( FTC_Node node, 00079 FTC_Manager manager ); 00080 #endif 00081 00082 00083 /*************************************************************************/ 00084 /*************************************************************************/ 00085 /***** *****/ 00086 /***** CACHE DEFINITIONS *****/ 00087 /***** *****/ 00088 /*************************************************************************/ 00089 /*************************************************************************/ 00090 00091 /* initialize a new cache node */ 00092 typedef FT_Error 00093 (*FTC_Node_NewFunc)( FTC_Node *pnode, 00094 FT_Pointer query, 00095 FTC_Cache cache ); 00096 00097 typedef FT_Offset 00098 (*FTC_Node_WeightFunc)( FTC_Node node, 00099 FTC_Cache cache ); 00100 00101 /* compare a node to a given key pair */ 00102 typedef FT_Bool 00103 (*FTC_Node_CompareFunc)( FTC_Node node, 00104 FT_Pointer key, 00105 FTC_Cache cache ); 00106 00107 00108 typedef void 00109 (*FTC_Node_FreeFunc)( FTC_Node node, 00110 FTC_Cache cache ); 00111 00112 typedef FT_Error 00113 (*FTC_Cache_InitFunc)( FTC_Cache cache ); 00114 00115 typedef void 00116 (*FTC_Cache_DoneFunc)( FTC_Cache cache ); 00117 00118 00119 typedef struct FTC_CacheClassRec_ 00120 { 00121 FTC_Node_NewFunc node_new; 00122 FTC_Node_WeightFunc node_weight; 00123 FTC_Node_CompareFunc node_compare; 00124 FTC_Node_CompareFunc node_remove_faceid; 00125 FTC_Node_FreeFunc node_free; 00126 00127 FT_Offset cache_size; 00128 FTC_Cache_InitFunc cache_init; 00129 FTC_Cache_DoneFunc cache_done; 00130 00131 } FTC_CacheClassRec; 00132 00133 00134 /* each cache really implements a dynamic hash table to manage its nodes */ 00135 typedef struct FTC_CacheRec_ 00136 { 00137 FT_UFast p; 00138 FT_UFast mask; 00139 FT_Long slack; 00140 FTC_Node* buckets; 00141 00142 FTC_CacheClassRec clazz; /* local copy, for speed */ 00143 00144 FTC_Manager manager; 00145 FT_Memory memory; 00146 FT_UInt index; /* in manager's table */ 00147 00148 FTC_CacheClass org_class; /* original class pointer */ 00149 00150 } FTC_CacheRec; 00151 00152 00153 #define FTC_CACHE( x ) ( (FTC_Cache)(x) ) 00154 #define FTC_CACHE_P( x ) ( (FTC_Cache*)(x) ) 00155 00156 00157 /* default cache initialize */ 00158 FT_LOCAL( FT_Error ) 00159 FTC_Cache_Init( FTC_Cache cache ); 00160 00161 /* default cache finalizer */ 00162 FT_LOCAL( void ) 00163 FTC_Cache_Done( FTC_Cache cache ); 00164 00165 /* Call this function to lookup the cache. If no corresponding 00166 * node is found, a new one is automatically created. This function 00167 * is capable of flushing the cache adequately to make room for the 00168 * new cache object. 00169 */ 00170 00171 #ifndef FTC_INLINE 00172 FT_LOCAL( FT_Error ) 00173 FTC_Cache_Lookup( FTC_Cache cache, 00174 FT_PtrDist hash, 00175 FT_Pointer query, 00176 FTC_Node *anode ); 00177 #endif 00178 00179 FT_LOCAL( FT_Error ) 00180 FTC_Cache_NewNode( FTC_Cache cache, 00181 FT_PtrDist hash, 00182 FT_Pointer query, 00183 FTC_Node *anode ); 00184 00185 /* Remove all nodes that relate to a given face_id. This is useful 00186 * when un-installing fonts. Note that if a cache node relates to 00187 * the face_id, but is locked (i.e., has `ref_count > 0'), the node 00188 * will _not_ be destroyed, but its internal face_id reference will 00189 * be modified. 00190 * 00191 * The final result will be that the node will never come back 00192 * in further lookup requests, and will be flushed on demand from 00193 * the cache normally when its reference count reaches 0. 00194 */ 00195 FT_LOCAL( void ) 00196 FTC_Cache_RemoveFaceID( FTC_Cache cache, 00197 FTC_FaceID face_id ); 00198 00199 00200 #ifdef FTC_INLINE 00201 00202 #define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \ 00203 FT_BEGIN_STMNT \ 00204 FTC_Node *_bucket, *_pnode, _node; \ 00205 FTC_Cache _cache = FTC_CACHE(cache); \ 00206 FT_PtrDist _hash = (FT_PtrDist)(hash); \ 00207 FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \ 00208 FT_UFast _idx; \ 00209 \ 00210 \ 00211 error = FTC_Err_Ok; \ 00212 node = NULL; \ 00213 _idx = _hash & _cache->mask; \ 00214 if ( _idx < _cache->p ) \ 00215 _idx = _hash & ( _cache->mask*2 + 1 ); \ 00216 \ 00217 _bucket = _pnode = _cache->buckets + _idx; \ 00218 for (;;) \ 00219 { \ 00220 _node = *_pnode; \ 00221 if ( _node == NULL ) \ 00222 goto _NewNode; \ 00223 \ 00224 if ( _node->hash == _hash && _nodcomp( _node, query, _cache ) ) \ 00225 break; \ 00226 \ 00227 _pnode = &_node->link; \ 00228 } \ 00229 \ 00230 if ( _node != *_bucket ) \ 00231 { \ 00232 *_pnode = _node->link; \ 00233 _node->link = *_bucket; \ 00234 *_bucket = _node; \ 00235 } \ 00236 \ 00237 { \ 00238 FTC_Manager _manager = _cache->manager; \ 00239 void* _nl = &_manager->nodes_list; \ 00240 \ 00241 \ 00242 if ( _node != _manager->nodes_list ) \ 00243 FTC_MruNode_Up( (FTC_MruNode*)_nl, \ 00244 (FTC_MruNode)_node ); \ 00245 } \ 00246 goto _Ok; \ 00247 \ 00248 _NewNode: \ 00249 error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \ 00250 \ 00251 _Ok: \ 00252 node = _node; \ 00253 FT_END_STMNT 00254 00255 #else /* !FTC_INLINE */ 00256 00257 #define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \ 00258 FT_BEGIN_STMNT \ 00259 error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, \ 00260 (FTC_Node*)&(node) ); \ 00261 FT_END_STMNT 00262 00263 #endif /* !FTC_INLINE */ 00264 00265 00266 /* 00267 * This macro, together with FTC_CACHE_TRYLOOP_END, defines a retry 00268 * loop to flush the cache repeatedly in case of memory overflows. 00269 * 00270 * It is used when creating a new cache node, or within a lookup 00271 * that needs to allocate data (e.g., the sbit cache lookup). 00272 * 00273 * Example: 00274 * 00275 * { 00276 * FTC_CACHE_TRYLOOP( cache ) 00277 * error = load_data( ... ); 00278 * FTC_CACHE_TRYLOOP_END() 00279 * } 00280 * 00281 */ 00282 #define FTC_CACHE_TRYLOOP( cache ) \ 00283 { \ 00284 FTC_Manager _try_manager = FTC_CACHE( cache )->manager; \ 00285 FT_UInt _try_count = 4; \ 00286 \ 00287 \ 00288 for (;;) \ 00289 { \ 00290 FT_UInt _try_done; 00291 00292 00293 #define FTC_CACHE_TRYLOOP_END() \ 00294 if ( !error || error != FTC_Err_Out_Of_Memory ) \ 00295 break; \ 00296 \ 00297 _try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \ 00298 if ( _try_done == 0 ) \ 00299 break; \ 00300 \ 00301 if ( _try_done == _try_count ) \ 00302 { \ 00303 _try_count *= 2; \ 00304 if ( _try_count < _try_done || \ 00305 _try_count > _try_manager->num_nodes ) \ 00306 _try_count = _try_manager->num_nodes; \ 00307 } \ 00308 } \ 00309 } 00310 00311 /* */ 00312 00313 FT_END_HEADER 00314 00315 00316 #endif /* __FTCCACHE_H__ */ 00317 00318 00319 /* END */ Generated on Sun May 27 2012 04:33:48 for ReactOS by
1.7.6.1
|