/src/3rdparty/freetype/src/cache/ftccache.h

https://bitbucket.org/ultra_iter/qt-vtl · C Header · 317 lines · 174 code · 61 blank · 82 comment · 21 complexity · b0bac4dfb9eb14694954abdc9f069663 MD5 · raw file

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