diff --git a/ChangeLog b/ChangeLog index 95d619a12..6fdcc8fe8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-09-21 David Turner + + * massive redesign of the cache sub-system internals. + in order to simplify the code and even slightly improve + performance (ftbench shows a 3% improvements in the SBit + and Image caches) + 2005-09-19 David Somers * freetype2/src/sfnt/ttload.c (sfnt_dir_check): Modified to allow a diff --git a/include/freetype/cache/ftccache.h b/include/freetype/cache/ftccache.h index f2e10281b..2e1c2164b 100644 --- a/include/freetype/cache/ftccache.h +++ b/include/freetype/cache/ftccache.h @@ -66,6 +66,8 @@ FT_BEGIN_HEADER #define FTC_NODE( x ) ( (FTC_Node)(x) ) #define FTC_NODE_P( x ) ( (FTC_Node*)(x) ) +#define FTC_NODE_REF(n) ( FTC_NODE(n)->ref_count += 1, (n) ) + #define FTC_NODE__NEXT(x) FTC_NODE( (x)->mru.next ) #define FTC_NODE__PREV(x) FTC_NODE( (x)->mru.prev ) @@ -103,9 +105,9 @@ FT_BEGIN_HEADER /* compare a node to a given key pair */ typedef FT_Bool - (*FTC_Node_CompareFunc)( FTC_Node node, - FT_Pointer key, - FTC_Cache cache ); + (*FTC_Node_EqualFunc)( FTC_Node node, + FT_Pointer key, + FTC_Cache cache ); typedef void @@ -123,8 +125,8 @@ FT_BEGIN_HEADER { FTC_Node_NewFunc node_new; FTC_Node_WeightFunc node_weight; - FTC_Node_CompareFunc node_compare; - FTC_Node_CompareFunc node_remove_faceid; + FTC_Node_EqualFunc node_equal; + FTC_Node_EqualFunc node_remove_faceid; FTC_Node_FreeFunc node_free; FT_UInt cache_size; @@ -134,21 +136,36 @@ FT_BEGIN_HEADER } FTC_CacheClassRec; +#define FTC_DEFINE_CACHE_CLASS(_n_new,_n_weight,_n_equal,_n_equal_faceid,_n_free,_c_type,_c_init,_c_done ) \ + { \ + (FTC_Node_NewFunc) (_n_new), \ + (FTC_Node_WeightFunc) (_n_weight), \ + (FTC_Node_EqualFunc) (_n_equal), \ + (FTC_Node_EqualFunc) (_n_equal_faceid), \ + (FTC_Node_FreeFunc) (_n_free), \ + \ + sizeof( _c_type ), \ + (FTC_Cache_InitFunc) (_c_init), \ + (FTC_Cache_DoneFunc) (_c_done) \ + } + + /* each cache really implements a dynamic hash table to manage its nodes */ typedef struct FTC_CacheRec_ { - FT_UFast p; - FT_UFast mask; - FT_Long slack; - FTC_Node* buckets; + FT_UFast p; + FT_UFast mask; + FT_Long slack; + FTC_Node* buckets; - FTC_CacheClassRec clazz; /* local copy, for speed */ + FTC_Node_EqualFunc node_equal; /* local copy of clazz->node_equal */ + FTC_Node_WeightFunc node_weight; /* local copy of clazz->node_weight */ - FTC_Manager manager; - FT_Memory memory; - FT_UInt index; /* in manager's table */ + FTC_Manager manager; + FT_Memory memory; + FT_UInt index; /* in manager's table */ - FTC_CacheClass org_class; /* original class pointer */ + FTC_CacheClass clazz; /* class pointer */ } FTC_CacheRec; @@ -156,6 +173,9 @@ FT_BEGIN_HEADER #define FTC_CACHE( x ) ( (FTC_Cache)(x) ) #define FTC_CACHE_P( x ) ( (FTC_Cache*)(x) ) +#define FTC_CACHE__CLASS(c) (FTC_CACHE(c)->clazz) +#define FTC_CACHE__MEMORY(c) (FTC_CACHE(c)->memory) +#define FTC_CACHE__MANAGER(c) (FTC_CACHE(c)->manager) /* default cache initialize */ FT_EXPORT( FT_Error ) @@ -201,11 +221,10 @@ FT_BEGIN_HEADER #define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \ FT_BEGIN_STMNT \ - FTC_Node *_bucket, *_pnode, _node; \ - FTC_Cache _cache = FTC_CACHE(cache); \ - FT_UInt32 _hash = (FT_UInt32)(hash); \ - FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \ - FT_UInt _idx; \ + FTC_Node *_bucket, *_pnode, _node; \ + FTC_Cache _cache = FTC_CACHE(cache); \ + FT_UInt32 _hash = (FT_UInt32)(hash); \ + FT_UInt _idx; \ \ \ error = 0; \ @@ -221,7 +240,7 @@ FT_BEGIN_HEADER if ( _node == NULL ) \ goto _NewNode; \ \ - if ( _node->hash == _hash && _nodcomp( _node, query, _cache ) ) \ + if ( _node->hash == _hash && nodecmp( _node, query, _cache ) ) \ break; \ \ _pnode = &_node->link; \ @@ -248,7 +267,7 @@ FT_BEGIN_HEADER error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \ \ _Ok: \ - _pnode = (FTC_Node*)(void*)&(node); \ + _pnode = (FTC_Node*)(void*)&(node); \ *_pnode = _node; \ FT_END_STMNT @@ -269,7 +288,7 @@ FT_BEGIN_HEADER * * It is used when creating a new cache node, or within a lookup * that needs to allocate data (e.g., the sbit cache lookup). - * + * * Example: * * { diff --git a/include/freetype/cache/ftcglyph.h b/include/freetype/cache/ftcglyph.h index 3f8301a51..ecb357ae9 100644 --- a/include/freetype/cache/ftcglyph.h +++ b/include/freetype/cache/ftcglyph.h @@ -58,7 +58,7 @@ * - 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_equal (must call FTC_GNode_Compare) * my_node_remove_faceid (must call ftc_gnode_unselect in case * of match) * @@ -68,9 +68,6 @@ * 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 @@ -116,7 +113,6 @@ #ifndef __FTCGLYPH_H__ #define __FTCGLYPH_H__ - #include #include FT_CACHE_INTERNAL_MANAGER_H @@ -124,6 +120,9 @@ FT_BEGIN_HEADER + typedef struct FTC_GCacheRec_* FTC_GCache; + + /* * We can group glyphs into `families'. Each family correspond to a * given face ID, character size, transform, etc. @@ -132,18 +131,72 @@ FT_BEGIN_HEADER * reference-counted. */ + typedef const struct FTC_FamilyClassRec_* FTC_FamilyClass; + 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_Family link; /* used for hashing too */ + FT_UInt32 hash; /* hash value for this family */ + FT_Int num_nodes; /* current number of nodes in this family */ + FTC_GCache cache; /* cache the family belongs to */ - } FTC_FamilyRec, *FTC_Family; + } FTC_FamilyRec; #define FTC_FAMILY(x) ( (FTC_Family)(x) ) #define FTC_FAMILY_P(x) ( (FTC_Family*)(x) ) +#define FTC_FAMILY__CACHE(f) (FTC_FAMILY(f)->cache) +#define FTC_FAMILY__CLASS(f) FTC_GCACHE__FAMILY_CLASS(FTC_FAMILY__CACHE(f)) + + /* note that the content of 'key' has already been copied to 'family' + * when this method is called. This callback is only necessary when you + * need to perform non-trivial initialization (e.g. duplicating + * heap-allocated memory, like strings, owned by the family) + * + * if this method returns an error, the corresponding FTC_Family_DoneFunc, + * will be called, if is not defined to NULL + */ + typedef FT_Error (*FTC_Family_InitFunc)( FTC_Family family, + FTC_Family key ); + + /* finalize the content of a given family object + */ + typedef void (*FTC_Family_DoneFunc)( FTC_Family family ); + + /* test wether a family matches a given key. Note that this method + * is only called when (family.hash == key.hash), so there is no + * need to test it again + */ + typedef FT_Bool (*FTC_Family_EqualFunc)( FTC_Family family, + FTC_Family key ); + + /* test wether a family matches a given FTC_FaceID + */ + typedef FT_Bool (*FTC_Family_EqualFaceIDFunc)( FTC_Family family, + FTC_FaceID face_id ); + + typedef struct FTC_FamilyClassRec_ + { + FT_UInt fam_size; + FTC_Family_InitFunc fam_init; + FTC_Family_DoneFunc fam_done; + FTC_Family_EqualFunc fam_equal; + FTC_Family_EqualFaceIDFunc fam_equal_faceid; + + } FTC_FamilyClassRec; + + +#define FTC_FAMILY_CLASS(x) ((FTC_FamilyClass)(x)) + +#define FTC_DEFINE_FAMILY_CLASS(_type,_init,_done,_equal,_equal_faceid) \ + { \ + sizeof(_type), \ + (FTC_Family_InitFunc) (_init), \ + (FTC_Family_DoneFunc) (_done), \ + (FTC_Family_EqualFunc) (_equal), \ + (FTC_Family_EqualFaceIDFunc)(_equal_faceid) \ + } + typedef struct FTC_GNodeRec_ { @@ -156,17 +209,6 @@ FT_BEGIN_HEADER #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 */ @@ -180,35 +222,46 @@ FT_BEGIN_HEADER FT_UInt gindex, /* glyph index for node */ FTC_Family family ); - /* 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 */ + /* this macro can be used to test wether a glyph node matches a given + * glyph query + */ +#define FTC_GNODE_EQUAL(node,key,cache) \ + ( FTC_GNODE(node)->family == FTC_GNODE(key)->family && \ + FTC_GNODE(node)->gindex == FTC_GNODE(key)->gindex ) + + + /* same as FTC_GNODE_EQUAL, but can be used as a callback */ FT_EXPORT( FT_Bool ) - FTC_GNode_Compare( FTC_GNode gnode, - FTC_GQuery gquery ); + FTC_GNode_Equal( FTC_GNode gnode, + FTC_GNode gquery, + FTC_GCache cache ); /* call this function to clear a node's family -- this is necessary */ /* to implement the `node_remove_faceid' cache method correctly */ - FT_EXPORT( void ) - FTC_GNode_UnselectFamily( FTC_GNode gnode, - FTC_Cache cache ); + FT_EXPORT( FT_Bool ) + FTC_GNode_EqualFaceID( FTC_GNode gnode, + FTC_FaceID face_id, + FTC_GCache cache ); /* must be called by derived FTC_Node_DoneFunc routines */ FT_EXPORT( void ) - FTC_GNode_Done( FTC_GNode node, - FTC_Cache cache ); + FTC_GNode_Done( FTC_GNode node ); FT_EXPORT( void ) FTC_Family_Init( FTC_Family family, - FTC_Cache cache ); + FT_UInt32 hash, + FTC_GCache cache ); + typedef struct FTC_GCacheRec_ { - FTC_CacheRec cache; - FTC_MruListRec families; + FTC_CacheRec cache; + FTC_Family_EqualFunc fam_equal; + FTC_Family_EqualFaceIDFunc fam_equal_faceid; + FTC_Family families; - } FTC_GCacheRec, *FTC_GCache; + } FTC_GCacheRec; #define FTC_GCACHE( x ) ((FTC_GCache)(x)) @@ -226,80 +279,112 @@ FT_BEGIN_HEADER /* the glyph cache class adds fields for the family implementation */ typedef struct FTC_GCacheClassRec_ { - FTC_CacheClassRec clazz; - FTC_MruListClass family_class; + FTC_CacheClassRec clazz; + FTC_FamilyClassRec family_class; } FTC_GCacheClassRec; typedef const FTC_GCacheClassRec* FTC_GCacheClass; + +#define FTC_DEFINE_GCACHE_CLASS(_cache_class,_family_class) \ + { \ + _cache_class, \ + _family_class \ + } + + #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 ) +#define FTC_GCACHE__CLASS( x ) \ + FTC_GCACHE_CLASS( FTC_CACHE__CLASS(x) ) + +#define FTC_GCACHE__FAMILY_CLASS(c) \ + (&FTC_GCACHE__CLASS(c)->family_class) - /* convenience function; use it instead of FTC_Manager_Register_Cache */ FT_EXPORT( FT_Error ) FTC_GCache_New( FTC_Manager manager, FTC_GCacheClass clazz, FTC_GCache *acache ); - FT_EXPORT( FT_Error ) - FTC_GCache_Lookup( FTC_GCache cache, - FT_UInt32 hash, - FT_UInt gindex, - FTC_GQuery query, - FTC_Node *anode ); + /* used by FTC_GCACHE_GET_FAMILY, don't call directly */ + FT_EXPORT( FT_Error ) + FTC_GCache_NewFamily( FTC_GCache cache, + FT_UInt32 hash, + FTC_Family query, + FTC_Family *afamily ); + + FT_EXPORT( void ) + FTC_GCache_FreeFamily( FTC_GCache cache, + FTC_Family family ); + +#define FTC_FAMILY_FREE(f) FTC_GCache_FreeFamily( (f)->cache, (f) ) + + /* query.hash must be set correctly !! */ + FT_EXPORT( FT_Error ) + FTC_GCache_GetFamily( FTC_GCache cache, + FT_UInt32 hash, + FTC_Family query, + FTC_Family *afamily ); + + /* query.family and query.gindex must be set correctly !! + */ + FT_EXPORT( FT_Error ) + FTC_GCache_GetNode( FTC_GCache cache, + FT_UInt32 hash, + FTC_GNode query, + FTC_Node *anode ); /* */ -#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); \ - \ - \ - _gquery->gindex = (gindex); \ - \ - FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare, \ - _gquery->family, error ); \ - 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 ); \ - } \ +#define FTC_GCACHE_GET_FAMILY( cache, famcmp, hash, key, family, error ) \ + FT_BEGIN_STMNT \ + FTC_GCache _gcache = FTC_GCACHE( cache ); \ + FTC_Family _key = FTC_FAMILY( key ); \ + FTC_Family_EqualFunc _fequal = (FTC_Family_EqualFunc)(famcmp); \ + FTC_Family* _pfamily = &_gcache->families; \ + FTC_Family _family; \ + \ + error = 0; \ + \ + for (;;) \ + { \ + _family = *_pfamily; \ + if ( _family == NULL ) \ + goto _NewFamily; \ + \ + if ( _family->hash == (hash) && _fequal( _family, _key ) ) \ + break; \ + \ + _pfamily = &_family->link; \ + } \ + \ + if ( _family != _gcache->families ) \ + { \ + *_pfamily = _family->link; \ + _family->link = _gcache->families; \ + _gcache->families = _family; \ + } \ + goto _FoundIt; \ + \ + _NewFamily: \ + error = FTC_GCache_NewFamily( _gcache, hash, _key, &_family ); \ + _FoundIt: \ + if ( !error ) \ + _family->num_nodes++; \ + \ + *(FTC_Family*)(void*)(family) = _family; \ 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 ), (FTC_Node*)&(node) ); \ - FT_END_STMNT +#define FTC_GCACHE_GET_FAMILY( cache, famcmp, key, family, error ) \ + error = FTC_GCache_GetFamily( (cache), (key), &(family) ) #endif /* !FTC_INLINE */ diff --git a/include/freetype/cache/ftcimage.h b/include/freetype/cache/ftcimage.h index 1bf12db13..d5046c6c9 100644 --- a/include/freetype/cache/ftcimage.h +++ b/include/freetype/cache/ftcimage.h @@ -23,7 +23,7 @@ * FTC_ICache extends FTC_GCache. For an implementation example, * see FTC_ImageCache in `src/cache/ftbasic.c'. */ - + /*************************************************************************/ /* */ @@ -51,35 +51,41 @@ FT_BEGIN_HEADER } FTC_INodeRec, *FTC_INode; -#define FTC_INODE( x ) ( (FTC_INode)( x ) ) -#define FTC_INODE_GINDEX( x ) FTC_GNODE(x)->gindex -#define FTC_INODE_FAMILY( x ) FTC_GNODE(x)->family +#define FTC_INODE( x ) ( (FTC_INode)( x ) ) +#define FTC_INODE__GLYPH(x) ( FTC_INODE(x)->glyph ) + typedef FT_Error - (*FTC_IFamily_LoadGlyphFunc)( FTC_Family family, - FT_UInt gindex, - FTC_Cache cache, - FT_Glyph *aglyph ); + (*FTC_IFamily_LoadGlyphFunc)( FTC_Family family, + FT_UInt gindex, + FTC_Manager manager, + FT_Glyph *aglyph ); - typedef struct FTC_IFamilyClassRec_ + typedef struct { - FTC_MruListClassRec clazz; - FTC_IFamily_LoadGlyphFunc family_load_glyph; + FTC_GCacheClassRec clazz; + FTC_IFamily_LoadGlyphFunc fam_load_glyph; - } FTC_IFamilyClassRec; + } FTC_ICacheClassRec; - typedef const FTC_IFamilyClassRec* FTC_IFamilyClass; + typedef const FTC_ICacheClassRec* FTC_ICacheClass; -#define FTC_IFAMILY_CLASS( x ) ((FTC_IFamilyClass)(x)) +#define FTC_ICACHE_CLASS(x) ((FTC_ICacheClass)(x)) -#define FTC_CACHE__IFAMILY_CLASS( x ) \ - FTC_IFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS(x)->family_class ) +#define FTC_ICACHE__CLASS(x) FTC_ICACHE_CLASS(FTC_GCACHE__CLASS(x)) +#define FTC_ICACHE__LOAD_GLYPH(x) (FTC_ICACHE__CLASS(x)->fam_load_glyph) + +#define FTC_DEFINE_ICACHE_CLASS(_gcache_class,_family_load_glyph) \ + { \ + _gcache_class, \ + (FTC_IFamily_LoadGlyphFunc) _family_load_glyph \ + } /* can be used as a @FTC_Node_FreeFunc */ FT_EXPORT( void ) - FTC_INode_Free( FTC_INode inode, - FTC_Cache cache ); + FTC_INode_Free( FTC_INode inode, + FTC_GCache cache ); /* Can be used as @FTC_Node_NewFunc. `gquery.index' and `gquery.family' * must be set correctly. This function will call the `family_load_glyph' @@ -87,8 +93,8 @@ FT_BEGIN_HEADER */ FT_EXPORT( FT_Error ) FTC_INode_New( FTC_INode *pinode, - FTC_GQuery gquery, - FTC_Cache cache ); + FTC_GNode gquery, + FTC_GCache cache ); /* can be used as @FTC_Node_WeightFunc */ FT_EXPORT( FT_ULong ) diff --git a/include/freetype/cache/ftcmru.h b/include/freetype/cache/ftcmru.h index ac1a1a92e..5638a7283 100644 --- a/include/freetype/cache/ftcmru.h +++ b/include/freetype/cache/ftcmru.h @@ -67,6 +67,8 @@ FT_BEGIN_HEADER } FTC_MruNodeRec; +#define FTC_MRUNODE(x) ((FTC_MruNode)(x)) + FT_EXPORT( void ) FTC_MruNode_Prepend( FTC_MruNode *plist, @@ -87,8 +89,8 @@ FT_BEGIN_HEADER typedef FT_Bool - (*FTC_MruNode_CompareFunc)( FTC_MruNode node, - FT_Pointer key ); + (*FTC_MruNode_EqualFunc)( FTC_MruNode node, + FT_Pointer key ); typedef FT_Error (*FTC_MruNode_InitFunc)( FTC_MruNode node, @@ -108,13 +110,22 @@ FT_BEGIN_HEADER typedef struct FTC_MruListClassRec_ { FT_UInt node_size; - FTC_MruNode_CompareFunc node_compare; + FTC_MruNode_EqualFunc node_equal; FTC_MruNode_InitFunc node_init; FTC_MruNode_ResetFunc node_reset; FTC_MruNode_DoneFunc node_done; } FTC_MruListClassRec; +#define FTC_DEFINE_MRULIST_CLASS(_type,_equal,_init,_reset,_done) \ + { \ + sizeof (_type), \ + (FTC_MruNode_EqualFunc) (_equal), \ + (FTC_MruNode_InitFunc) (_init), \ + (FTC_MruNode_ResetFunc) (_reset), \ + (FTC_MruNode_DoneFunc) (_done) \ + } + typedef struct FTC_MruListRec_ { FT_UInt num_nodes; @@ -162,7 +173,7 @@ FT_BEGIN_HEADER FT_EXPORT( void ) FTC_MruList_RemoveSelection( FTC_MruList list, - FTC_MruNode_CompareFunc selection, + FTC_MruNode_EqualFunc selection, FT_Pointer key ); @@ -170,9 +181,9 @@ FT_BEGIN_HEADER #define FTC_MRULIST_LOOKUP_CMP( list, key, compare, node, error ) \ FT_BEGIN_STMNT \ - FTC_MruNode* _pfirst = &(list)->nodes; \ - FTC_MruNode_CompareFunc _compare = (FTC_MruNode_CompareFunc)(compare); \ - FTC_MruNode _first, _node, *_pnode; \ + FTC_MruNode* _pfirst = &(list)->nodes; \ + FTC_MruNode_EqualFunc _compare = (FTC_MruNode_EqualFunc)(compare); \ + FTC_MruNode _first, _node, *_pnode; \ \ \ error = 0; \ @@ -204,7 +215,7 @@ FT_BEGIN_HEADER FT_END_STMNT #define FTC_MRULIST_LOOKUP( list, key, node, error ) \ - FTC_MRULIST_LOOKUP_CMP( list, key, (list)->clazz.node_compare, node, error ) + FTC_MRULIST_LOOKUP_CMP( list, key, (list)->clazz.node_equal, node, error ) #else /* !FTC_INLINE */ @@ -213,29 +224,6 @@ FT_BEGIN_HEADER #endif /* !FTC_INLINE */ - -#define FTC_MRULIST_LOOP( list, node ) \ - FT_BEGIN_STMNT \ - FTC_MruNode _first = (list)->nodes; \ - \ - \ - if ( _first ) \ - { \ - FTC_MruNode _node = _first; \ - \ - \ - do \ - { \ - *(FTC_MruNode*)&(node) = _node; - - -#define FTC_MRULIST_LOOP_END() \ - _node = _node->next; \ - \ - } while ( _node != _first ); \ - } \ - FT_END_STMNT - /* */ FT_END_HEADER diff --git a/include/freetype/cache/ftcsbits.h b/include/freetype/cache/ftcsbits.h index b2ef0f181..e07d5080c 100644 --- a/include/freetype/cache/ftcsbits.h +++ b/include/freetype/cache/ftcsbits.h @@ -39,8 +39,8 @@ FT_BEGIN_HEADER #define FTC_SNODE( x ) ( (FTC_SNode)( x ) ) -#define FTC_SNODE_GINDEX( x ) FTC_GNODE( x )->gindex -#define FTC_SNODE_FAMILY( x ) FTC_GNODE( x )->family +#define FTC_SNODE__COUNT(x) ( FTC_SNODE(x)->count ) + typedef FT_UInt (*FTC_SFamily_GetCountFunc)( FTC_Family family, @@ -52,40 +52,54 @@ FT_BEGIN_HEADER FTC_Manager manager, FT_Face *aface ); - typedef struct FTC_SFamilyClassRec_ + typedef struct { - FTC_MruListClassRec clazz; - FTC_SFamily_GetCountFunc family_get_count; - FTC_SFamily_LoadGlyphFunc family_load_glyph; + FTC_GCacheClassRec clazz; + FTC_SFamily_GetCountFunc fam_get_count; + FTC_SFamily_LoadGlyphFunc fam_load_glyph; - } FTC_SFamilyClassRec; + } FTC_SCacheClassRec; - typedef const FTC_SFamilyClassRec* FTC_SFamilyClass; + typedef const FTC_SCacheClassRec* FTC_SCacheClass; + +#define FTC_SCACHE_CLASS(x) ((FTC_SCacheClass)(x)) +#define FTC_SCACHE__CLASS(c) FTC_SCACHE_CLASS(FTC_CACHE__CLASS(c)) + +#define FTC_DEFINE_SCACHE_CLASS(_gcache_class,_get_count,_get_glyph) \ + { \ + _gcache_class, \ + (FTC_SFamily_GetCountFunc) (_get_count), \ + (FTC_SFamily_LoadGlyphFunc)(_get_glyph) \ + } + +#define FTC_SFAMILY__CLASS(f) FTC_SCACHE__CLASS(FTC_FAMILY__CACHE(f)) -#define FTC_SFAMILY_CLASS( x ) ((FTC_SFamilyClass)(x)) #define FTC_CACHE__SFAMILY_CLASS( x ) \ FTC_SFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS( x )->family_class ) FT_EXPORT( void ) - FTC_SNode_Free( FTC_SNode snode, - FTC_Cache cache ); + FTC_SNode_Free( FTC_SNode snode, + FTC_GCache cache ); FT_EXPORT( FT_Error ) FTC_SNode_New( FTC_SNode *psnode, - FTC_GQuery gquery, - FTC_Cache cache ); + FTC_GNode gquery, + FTC_GCache cache ); + +#define FTC_SNODE_EQUAL(node,query,cache) \ + FTC_SNode_Equal( FTC_SNODE(node), FTC_GNODE(query), FTC_CACHE(cache) ) + + FT_EXPORT( FT_Bool ) + FTC_SNode_Equal( FTC_SNode snode, + FTC_GNode gquery, + FTC_Cache cache ); FT_EXPORT( FT_ULong ) FTC_SNode_Weight( FTC_SNode inode ); - FT_EXPORT( FT_Bool ) - FTC_SNode_Compare( FTC_SNode snode, - FTC_GQuery gquery, - FTC_Cache cache ); - /* */ FT_END_HEADER diff --git a/include/freetype/ftcache.h b/include/freetype/ftcache.h index 985641c1b..20e9a1edb 100644 --- a/include/freetype/ftcache.h +++ b/include/freetype/ftcache.h @@ -246,6 +246,21 @@ FT_BEGIN_HEADER typedef struct FTC_NodeRec_* FTC_Node; + /*************************************************************************/ + /* */ + /* */ + /* FTC_Family */ + /* */ + /* */ + /* An opaque handle to a cache family object. A family is used to */ + /* group the attributes of several similar cache nodes. */ + /* */ + /* Each family is reference-counted. When its count reaches 0, it */ + /* is immediately destroyed. */ + /* */ + typedef struct FTC_FamilyRec_* FTC_Family; + + /*************************************************************************/ /* */ /* */ @@ -449,12 +464,75 @@ FT_BEGIN_HEADER FTC_Manager manager ); + /** + * @func: FTC_Family_Unref + * + * @description: + * decrement a cache family's internal reference count. When its reaches + * the value 0, it is destroyed immediately. You should always destroy + * family objects as soon as possible. + */ + FT_EXPORT( void ) + FTC_Family_Unref( FTC_Family family ); + + /* remove all nodes belonging to a given face_id */ FT_EXPORT( void ) FTC_Manager_RemoveFaceID( FTC_Manager manager, FTC_FaceID face_id ); + /** + * @type: FTC_ImgMode + * + * @description: + * this simple 32-bit unsigned integer type is used to store + * styling and pixel rendering options + * + * see @FTC_IMGMODE_MAKE, @FTC_IMGMODE_GET_RENDER, @FTC_IMGMODE_GET_EMBOLDEN + * and @FTC_IMGMODE_GET_OBLIQUE + */ +typedef FT_UInt32 FTC_ImgMode; + + /** + * @macro: FTC_IMGMODE_MAKE + * + * @description: + * a convenient macro used to build a @FTC_ImgMode value that describes + * pixel rendering mode, emboldening flag, and obliquing flag + * + * @param: + * render :: pixel rendering mode, see @FT_Render_Mode + * bold :: boolean, true if emboldening is wanted + * ital :: boolean, true if obliquing is wanted + */ +#define FTC_IMGMODE_MAKE(render,bold,ital) \ + ((FTC_ImgMode)(((render) << 2) | (((bold) != 0) << 1) | ((ital) != 0) ) + + /** + * @macro: FTC_IMGMODE_GET_RENDER (mode) + * + * @description: + * retrieve the render mode of a given @FTC_ImgMode value + */ +#define FTC_IMGMODE_GET_RENDER(m) ((FT_Render_Mode)((m) >> 2)) + + /** + * @macro: FTC_IMGMODE_GET_EMBOLDEN (mode) + * + * @description: + * retrieve the emboldening flags from a @FTC_ImgMode value + */ +#define FTC_IMGMODE_GET_EMBOLDEN(m) (((m) & 0x2) != 0) + + /** + * @macro: FTC_IMGMODE_GET_OBLIQUE (mode) + * + * @description: + * retrive the obliquing flag from a @FTC_ImgMode value + */ +#define FTC_IMGMODE_GET_OBLIQUE(m) (((m) & 0x1) != 0) + /*************************************************************************/ /* */ /*
*/ @@ -653,6 +731,29 @@ FT_BEGIN_HEADER FTC_Node *anode ); + FT_EXPORT( FT_Error ) + FTC_ImageCache_GetFamily( FTC_ImageCache cache, + FTC_Scaler scaler, + FT_UInt32 load_flags, + FTC_ImgMode img_mode, + FTC_Family *afamily ); + + FT_EXPORT( FT_Error ) + FTC_ImageCache_GetGlyph( FTC_ImageCache cache, + FTC_Family family, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ); + + FT_EXPORT( FT_Error ) + FTC_ImageCache_FindGlyph( FTC_ImageCache cache, + FTC_Scaler scaler, + FT_UInt32 load_flags, + FTC_ImgMode img_mode, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ); + /*************************************************************************/ /* */ /* */ @@ -806,6 +907,96 @@ FT_BEGIN_HEADER FTC_SBit *sbit, FTC_Node *anode ); + /** + * @func: FTC_SBitCache_GetFamily + * + * @description: + * retrieve the @FTC_Family from a @FTC_SBitCache that corresponds + * to a given set of scaling mode, load flags and image modes. + * + * @input: + * cache :: handle to source SBit cache + * scaler :: handle to @FTC_ScalerRec structure describing scaling parameters + * load_flags :: load flags + * image_modes :: corresponds to rendering pixel mode, emboldening and obliquing + * + * @output: + * afamily :: handle to family. NULL in case of error + * + * @return: + * error code + * + * @note: + * you should free the family handle with @FTC_Family_Unref + */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_GetFamily( FTC_SBitCache cache, + FTC_Scaler scaler, + FT_UInt32 load_flags, + FTC_ImgMode img_mode, + FTC_Family *afamily ); + + /** + * @func: FTC_SBitCache_GetBitmap + * + * @description: + * retrieve a bitmap from a SBit cache using a @FTC_Family previously + * found with @TC_SBitCache_GetFamily. The same family can be used in + * subsequent calls + * + * @input: + * cache :: handle to source SBit cache + * family :: family handle + * gindex :: glyph index + * + * @output: + * asbit :: handle to small bitmap descriptor + * + * @inout: + * anode :: address where the handle to the corresponding cache node + * will be written. set to NULL if you don't need it. + * + * @note: + * the small bitmap descriptor whose address is managed by the cache + * + * if 'anode' is not NULL on input, you must call @FTC_Node_Unref(*anode) + * when you don't need to cache node. + */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_GetBitmap( FTC_SBitCache cache, + FTC_Family family, + FT_UInt gindex, + FTC_SBit *asbit, + FTC_Node *anode ); + + /** + * @func: FTC_SBitCache_FindBitmap + * + * @description: + * a convenience function equivalent to the following sequence: + * + * { + * FTC_Family family; + * + * error = FTC_SBitCache_GetFamily( cache, scaler, load_flags, img_mode, + * &family ); + * if ( !error ) + * { + * error = FTC_SBitCache_GetBitmap( cache, family, gindex, asbit, anode ); + * + * FTC_Family_Unref( family ); + * } + * } + * + */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_FindBitmap( FTC_SBitCache cache, + FTC_Scaler scaler, + FT_UInt32 load_flags, + FTC_ImgMode img_mode, + FT_UInt gindex, + FTC_SBit *asbit, + FTC_Node *anode ); /* */ diff --git a/src/cache/ftcbasic.c b/src/cache/ftcbasic.c index 689cdc61b..4e7209af8 100644 --- a/src/cache/ftcbasic.c +++ b/src/cache/ftcbasic.c @@ -23,7 +23,6 @@ #include FT_CACHE_INTERNAL_SBITS_H #include FT_INTERNAL_MEMORY_H -#include "ftccback.h" #include "ftcerror.h" @@ -31,77 +30,46 @@ * Basic Families * */ - typedef struct FTC_BasicAttrRec_ - { - FTC_ScalerRec scaler; - FT_UInt load_flags; - - } FTC_BasicAttrRec, *FTC_BasicAttrs; - -#define FTC_BASIC_ATTR_COMPARE( a, b ) \ - FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \ - (a)->load_flags == (b)->load_flags ) - -#define FTC_BASIC_ATTR_HASH( a ) \ - ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags ) - - - typedef struct FTC_BasicQueryRec_ - { - FTC_GQueryRec gquery; - FTC_BasicAttrRec attrs; - - } FTC_BasicQueryRec, *FTC_BasicQuery; - - typedef struct FTC_BasicFamilyRec_ { - FTC_FamilyRec family; - FTC_BasicAttrRec attrs; + FTC_FamilyRec family; + FTC_ScalerRec scaler; + FT_UInt load_flags; } FTC_BasicFamilyRec, *FTC_BasicFamily; +#define FTC_BASIC_FAMILY_HASH(f) \ + ( FTC_SCALER_HASH( &(f)->scaler ) + 31*(f)->load_flags ) + + FT_CALLBACK_DEF( FT_Bool ) - ftc_basic_family_compare( FTC_MruNode ftcfamily, - FT_Pointer ftcquery ) + ftc_basic_family_equal( FTC_BasicFamily family, + FTC_BasicFamily query ) { - FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; - FTC_BasicQuery query = (FTC_BasicQuery)ftcquery; - - - return FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs ); + return ( FTC_SCALER_COMPARE( &(family)->scaler, &(query)->scaler ) && + family->load_flags == query->load_flags ); } - FT_CALLBACK_DEF( FT_Error ) - ftc_basic_family_init( FTC_MruNode ftcfamily, - FT_Pointer ftcquery, - FT_Pointer ftccache ) + FT_CALLBACK_DEF( FT_Bool ) + ftc_basic_family_equal_faceid( FTC_BasicFamily family, + FTC_FaceID face_id ) { - FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; - FTC_BasicQuery query = (FTC_BasicQuery)ftcquery; - FTC_Cache cache = (FTC_Cache)ftccache; - - - FTC_Family_Init( FTC_FAMILY( family ), cache ); - family->attrs = query->attrs; - return 0; + return FT_BOOL( family->scaler.face_id == face_id ); } FT_CALLBACK_DEF( FT_UInt ) - ftc_basic_family_get_count( FTC_Family ftcfamily, - FTC_Manager manager ) + ftc_basic_family_get_count( FTC_BasicFamily family, + FTC_Manager manager ) { - FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; - FT_Error error; - FT_Face face; - FT_UInt result = 0; + FT_Error error; + FT_Face face; + FT_UInt result = 0; - error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id, - &face ); + error = FTC_Manager_LookupFace( manager, family->scaler.face_id, &face ); if ( !error ) result = face->num_glyphs; @@ -110,24 +78,23 @@ FT_CALLBACK_DEF( FT_Error ) - ftc_basic_family_load_bitmap( FTC_Family ftcfamily, - FT_UInt gindex, - FTC_Manager manager, - FT_Face *aface ) + ftc_basic_family_load_bitmap( FTC_BasicFamily family, + FT_UInt gindex, + FTC_Manager manager, + FT_Face *aface ) { - FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; FT_Error error; FT_Size size; - error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size ); + error = FTC_Manager_LookupSize( manager, &family->scaler, &size ); if ( !error ) { FT_Face face = size->face; error = FT_Load_Glyph( face, gindex, - family->attrs.load_flags | FT_LOAD_RENDER ); + family->load_flags | FT_LOAD_RENDER ); if ( !error ) *aface = face; } @@ -137,27 +104,24 @@ FT_CALLBACK_DEF( FT_Error ) - ftc_basic_family_load_glyph( FTC_Family ftcfamily, - FT_UInt gindex, - FTC_Cache cache, - FT_Glyph *aglyph ) + ftc_basic_family_load_glyph( FTC_BasicFamily family, + FT_UInt gindex, + FTC_Manager manager, + FT_Glyph *aglyph ) { - FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; - FT_Error error; - FTC_Scaler scaler = &family->attrs.scaler; - FT_Face face; - FT_Size size; + FT_Error error; + FTC_Scaler scaler = &family->scaler; + FT_Face face; + FT_Size size; /* we will now load the glyph image */ - error = FTC_Manager_LookupSize( cache->manager, - scaler, - &size ); + error = FTC_Manager_LookupSize( manager, scaler, &size ); if ( !error ) { face = size->face; - error = FT_Load_Glyph( face, gindex, family->attrs.load_flags ); + error = FT_Load_Glyph( face, gindex, family->load_flags ); if ( !error ) { if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || @@ -184,29 +148,6 @@ } - FT_CALLBACK_DEF( FT_Bool ) - ftc_basic_gnode_compare_faceid( FTC_Node ftcgnode, - FT_Pointer ftcface_id, - FTC_Cache cache ) - { - FTC_GNode gnode = (FTC_GNode)ftcgnode; - FTC_FaceID face_id = (FTC_FaceID)ftcface_id; - FTC_BasicFamily family = (FTC_BasicFamily)gnode->family; - FT_Bool result; - - - result = FT_BOOL( family->attrs.scaler.face_id == face_id ); - if ( result ) - { - /* we must call this function to avoid this node from appearing - * in later lookups with the same face_id! - */ - FTC_GNode_UnselectFamily( gnode, cache ); - } - return result; - } - - /* * * basic image cache @@ -214,36 +155,29 @@ */ FT_CALLBACK_TABLE_DEF - const FTC_IFamilyClassRec ftc_basic_image_family_class = - { - { - sizeof ( FTC_BasicFamilyRec ), - ftc_basic_family_compare, - ftc_basic_family_init, - 0, /* FTC_MruNode_ResetFunc */ - 0 /* FTC_MruNode_DoneFunc */ - }, - ftc_basic_family_load_glyph - }; - - - FT_CALLBACK_TABLE_DEF - const FTC_GCacheClassRec ftc_basic_image_cache_class = - { - { - ftc_inode_new, - ftc_inode_weight, - ftc_gnode_compare, - ftc_basic_gnode_compare_faceid, - ftc_inode_free, - - sizeof ( FTC_GCacheRec ), - ftc_gcache_init, - ftc_gcache_done - }, - (FTC_MruListClass)&ftc_basic_image_family_class - }; - + const FTC_ICacheClassRec ftc_basic_image_cache_class = + FTC_DEFINE_ICACHE_CLASS( + FTC_DEFINE_GCACHE_CLASS( + FTC_DEFINE_CACHE_CLASS( + FTC_INode_New, + FTC_INode_Weight, + FTC_GNode_Equal, + FTC_GNode_EqualFaceID, + FTC_INode_Free, + FTC_GCacheRec, + FTC_GCache_Init, + FTC_GCache_Done + ), + FTC_DEFINE_FAMILY_CLASS( + FTC_BasicFamilyRec, + 0 /* init */, + 0 /* done */, + ftc_basic_family_equal, + ftc_basic_family_equal_faceid + ) + ), + ftc_basic_family_load_glyph + ); /* documentation is in ftcache.h */ @@ -251,8 +185,9 @@ FTC_ImageCache_New( FTC_Manager manager, FTC_ImageCache *acache ) { - return FTC_GCache_New( manager, &ftc_basic_image_cache_class, - (FTC_GCache*)acache ); + return FTC_Manager_RegisterCache( manager, + (FTC_CacheClass) &ftc_basic_image_cache_class, + (FTC_Cache*)acache ); } @@ -265,10 +200,11 @@ FT_Glyph *aglyph, FTC_Node *anode ) { - FTC_BasicQueryRec query; - FTC_INode node = 0; /* make compiler happy */ - FT_Error error; - FT_UInt32 hash; + FTC_BasicFamilyRec key_family; + FTC_GNodeRec key; + FTC_Node node = 0; /* make compiler happy */ + FT_Error error; + FT_UInt32 hash; /* some argument checks are delayed to FTC_Cache_Lookup */ @@ -282,40 +218,34 @@ if ( anode ) *anode = NULL; - query.attrs.scaler.face_id = type->face_id; - query.attrs.scaler.width = type->width; - query.attrs.scaler.height = type->height; - query.attrs.scaler.pixel = 1; - query.attrs.load_flags = type->flags; + key_family.scaler.face_id = type->face_id; + key_family.scaler.width = type->width; + key_family.scaler.height = type->height; + key_family.scaler.pixel = 1; + key_family.scaler.x_res = 0; /* make compilers happy */ + key_family.scaler.y_res = 0; + key_family.load_flags = type->flags; - query.attrs.scaler.x_res = 0; /* make compilers happy */ - query.attrs.scaler.y_res = 0; + hash = FTC_BASIC_FAMILY_HASH( &key_family ); - hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex; - -#if 1 /* inlining is about 50% faster! */ - FTC_GCACHE_LOOKUP_CMP( cache, - ftc_basic_family_compare, - FTC_GNode_Compare, - hash, gindex, - &query, - node, - error ); -#else - error = FTC_GCache_Lookup( FTC_GCACHE( cache ), - hash, gindex, - FTC_GQUERY( &query ), - (FTC_Node*) &node ); -#endif + FTC_GCACHE_GET_FAMILY( cache, ftc_basic_family_equal, + hash, &key_family, &key.family, error ); if ( !error ) { - *aglyph = FTC_INODE( node )->glyph; + hash += gindex; + key.gindex = gindex; - if ( anode ) + FTC_CACHE_LOOKUP_CMP( cache, FTC_GNODE_EQUAL, hash, + &key, node, error ); + if ( !error ) { - *anode = FTC_NODE( node ); - FTC_NODE( node )->ref_count++; + *aglyph = FTC_INODE( node )->glyph; + + if ( anode ) + *anode = FTC_NODE_REF( node ); } + + FTC_Family_Unref( FTC_FAMILY(key.family) ); } Exit: @@ -328,40 +258,31 @@ * basic small bitmap cache * */ - - FT_CALLBACK_TABLE_DEF - const FTC_SFamilyClassRec ftc_basic_sbit_family_class = - { - { - sizeof( FTC_BasicFamilyRec ), - ftc_basic_family_compare, - ftc_basic_family_init, - 0, /* FTC_MruNode_ResetFunc */ - 0 /* FTC_MruNode_DoneFunc */ - }, - ftc_basic_family_get_count, - ftc_basic_family_load_bitmap - }; - - - FT_CALLBACK_TABLE_DEF - const FTC_GCacheClassRec ftc_basic_sbit_cache_class = - { - { - ftc_snode_new, - ftc_snode_weight, - ftc_snode_compare, - ftc_basic_gnode_compare_faceid, - ftc_snode_free, - - sizeof ( FTC_GCacheRec ), - ftc_gcache_init, - ftc_gcache_done - }, - (FTC_MruListClass)&ftc_basic_sbit_family_class - }; - + const FTC_SCacheClassRec ftc_basic_sbit_cache_class = + FTC_DEFINE_SCACHE_CLASS( + FTC_DEFINE_GCACHE_CLASS( + FTC_DEFINE_CACHE_CLASS( + FTC_SNode_New, + FTC_SNode_Weight, + FTC_SNode_Equal, + FTC_GNode_EqualFaceID, + FTC_SNode_Free, + FTC_GCacheRec, + FTC_GCache_Init, + FTC_GCache_Done + ), + FTC_DEFINE_FAMILY_CLASS( + FTC_BasicFamilyRec, + 0 /* init */, + 0 /* done */, + ftc_basic_family_equal, + ftc_basic_family_equal_faceid + ) + ), + ftc_basic_family_get_count, + ftc_basic_family_load_bitmap + ); /* documentation is in ftcache.h */ @@ -369,8 +290,9 @@ FTC_SBitCache_New( FTC_Manager manager, FTC_SBitCache *acache ) { - return FTC_GCache_New( manager, &ftc_basic_sbit_cache_class, - (FTC_GCache*)acache ); + return FTC_Manager_RegisterCache( manager, + (FTC_CacheClass) &ftc_basic_sbit_cache_class, + (FTC_Cache*)acache ); } @@ -383,10 +305,11 @@ FTC_SBit *ansbit, FTC_Node *anode ) { - FT_Error error; - FTC_BasicQueryRec query; - FTC_SNode node = 0; /* make compiler happy */ - FT_UInt32 hash; + FTC_BasicFamilyRec key_family; + FTC_GNodeRec key; + FT_Error error; + FTC_Node node = 0; /* make compiler happy */ + FT_UInt32 hash; if ( anode ) @@ -398,48 +321,39 @@ *ansbit = NULL; - query.attrs.scaler.face_id = type->face_id; - query.attrs.scaler.width = type->width; - query.attrs.scaler.height = type->height; - query.attrs.scaler.pixel = 1; - query.attrs.load_flags = type->flags; + key_family.scaler.face_id = type->face_id; + key_family.scaler.width = type->width; + key_family.scaler.height = type->height; + key_family.scaler.pixel = 1; + key_family.scaler.x_res = 0; /* make compilers happy */ + key_family.scaler.y_res = 0; + key_family.load_flags = type->flags; - query.attrs.scaler.x_res = 0; /* make compilers happy */ - query.attrs.scaler.y_res = 0; + hash = FTC_BASIC_FAMILY_HASH( &key_family ); - /* beware, the hash must be the same for all glyph ranges! */ - hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + - gindex / FTC_SBIT_ITEMS_PER_NODE; - -#if 1 /* inlining is about 50% faster! */ - FTC_GCACHE_LOOKUP_CMP( cache, - ftc_basic_family_compare, - FTC_SNode_Compare, - hash, gindex, - &query, - node, - error ); -#else - error = FTC_GCache_Lookup( FTC_GCACHE( cache ), - hash, - gindex, - FTC_GQUERY( &query ), - (FTC_Node*)&node ); -#endif - if ( error ) - goto Exit; - - *ansbit = node->sbits + ( gindex - FTC_GNODE( node )->gindex ); - - if ( anode ) + FTC_GCACHE_GET_FAMILY( cache, ftc_basic_family_equal, + hash, &key_family, &key.family, error ); + if ( !error ) { - *anode = FTC_NODE( node ); - FTC_NODE( node )->ref_count++; + /* beware, the hash must be the same for all glyph ranges */ + hash += gindex/FTC_SBIT_ITEMS_PER_NODE; + + key.gindex = gindex; + + FTC_CACHE_LOOKUP_CMP( cache, FTC_SNODE_EQUAL, hash, + &key, node, error ); + if ( !error ) + { + *ansbit = FTC_SNODE(node)->sbits + ( gindex - FTC_GNODE(node)->gindex ); + + if ( anode ) + *anode = FTC_NODE_REF(node); + } + + FTC_Family_Unref( FTC_FAMILY(key.family) ); } - Exit: return error; } - /* END */ diff --git a/src/cache/ftccache.c b/src/cache/ftccache.c index ad036805f..aaf3bd8c1 100644 --- a/src/cache/ftccache.c +++ b/src/cache/ftccache.c @@ -21,7 +21,6 @@ #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H -#include "ftccback.h" #include "ftcerror.h" @@ -272,7 +271,7 @@ } #endif - manager->cur_weight -= cache->clazz.node_weight( node, cache ); + manager->cur_weight -= cache->node_weight( node, cache ); /* remove node from mru list */ ftc_node_mru_unlink( node, manager ); @@ -281,7 +280,7 @@ ftc_node_hash_unlink( node, cache ); /* now finalize it */ - cache->clazz.node_free( node, cache ); + cache->clazz->node_free( node, cache ); #if 0 /* check, just in case of general corruption :-) */ @@ -303,13 +302,6 @@ FT_EXPORT_DEF( FT_Error ) FTC_Cache_Init( FTC_Cache cache ) - { - return ftc_cache_init( cache ); - } - - - FT_LOCAL_DEF( FT_Error ) - ftc_cache_init( FTC_Cache cache ) { FT_Memory memory = cache->memory; @@ -322,6 +314,7 @@ } + FT_EXPORT_DEF( void ) FTC_Cache_Clear( FTC_Cache cache ) { @@ -348,9 +341,9 @@ ftc_node_mru_unlink( node, manager ); /* now finalize it */ - manager->cur_weight -= cache->clazz.node_weight( node, cache ); + manager->cur_weight -= cache->node_weight( node, cache ); - cache->clazz.node_free( node, cache ); + cache->clazz->node_free( node, cache ); node = next; } cache->buckets[i] = NULL; @@ -360,8 +353,8 @@ } - FT_LOCAL_DEF( void ) - ftc_cache_done( FTC_Cache cache ) + FT_EXPORT_DEF( void ) + FTC_Cache_Done( FTC_Cache cache ) { if ( cache->memory ) { @@ -380,13 +373,6 @@ } - FT_EXPORT_DEF( void ) - FTC_Cache_Done( FTC_Cache cache ) - { - ftc_cache_done( cache ); - } - - static void ftc_cache_add( FTC_Cache cache, FT_UInt32 hash, @@ -403,7 +389,7 @@ FTC_Manager manager = cache->manager; - manager->cur_weight += cache->clazz.node_weight( node, cache ); + manager->cur_weight += cache->node_weight( node, cache ); if ( manager->cur_weight >= manager->max_weight ) { @@ -433,7 +419,7 @@ FTC_CACHE_TRYLOOP( cache ) { - error = cache->clazz.node_new( &node, query, cache ); + error = cache->clazz->node_new( &node, query, cache ); } FTC_CACHE_TRYLOOP_END(); @@ -464,7 +450,7 @@ FTC_Node node; FT_Error error = 0; - FTC_Node_CompareFunc compare = cache->clazz.node_compare; + FTC_Node_EqualFunc compare = cache->node_equal; if ( cache == NULL || anode == NULL ) @@ -535,7 +521,7 @@ if ( node == NULL ) break; - if ( cache->clazz.node_remove_faceid( node, face_id, cache ) ) + if ( cache->clazz->node_remove_faceid( node, face_id, cache ) ) { *pnode = node->link; node->link = frees; @@ -555,10 +541,10 @@ node = frees; frees = node->link; - manager->cur_weight -= cache->clazz.node_weight( node, cache ); + manager->cur_weight -= cache->node_weight( node, cache ); ftc_node_mru_unlink( node, manager ); - cache->clazz.node_free( node, cache ); + cache->clazz->node_free( node, cache ); cache->slack++; } diff --git a/src/cache/ftccback.h b/src/cache/ftccback.h deleted file mode 100644 index 6b47e095e..000000000 --- a/src/cache/ftccback.h +++ /dev/null @@ -1,85 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftccback.h */ -/* */ -/* Callback functions of the caching sub-system (specification only). */ -/* */ -/* Copyright 2004 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. */ -/* */ -/***************************************************************************/ - -#ifndef __FTCCBACK_H__ -#define __FTCCBACK_H__ - -#include -#include FT_CACHE_H -#include FT_CACHE_INTERNAL_MRU_H -#include FT_CACHE_INTERNAL_IMAGE_H -#include FT_CACHE_INTERNAL_MANAGER_H -#include FT_CACHE_INTERNAL_GLYPH_H -#include FT_CACHE_INTERNAL_SBITS_H - - - FT_LOCAL( void ) - ftc_inode_free( FTC_Node inode, - FTC_Cache cache ); - - FT_LOCAL( FT_Error ) - ftc_inode_new( FTC_Node *pinode, - FT_Pointer gquery, - FTC_Cache cache ); - - FT_LOCAL( FT_ULong ) - ftc_inode_weight( FTC_Node inode, - FTC_Cache cache ); - - - FT_LOCAL( void ) - ftc_snode_free( FTC_Node snode, - FTC_Cache cache ); - - FT_LOCAL( FT_Error ) - ftc_snode_new( FTC_Node *psnode, - FT_Pointer gquery, - FTC_Cache cache ); - - FT_LOCAL( FT_ULong ) - ftc_snode_weight( FTC_Node snode, - FTC_Cache cache ); - - FT_LOCAL( FT_Bool ) - ftc_snode_compare( FTC_Node snode, - FT_Pointer gquery, - FTC_Cache cache ); - - - FT_LOCAL( FT_Bool ) - ftc_gnode_compare( FTC_Node gnode, - FT_Pointer gquery, - FTC_Cache cache ); - - - FT_LOCAL( FT_Error ) - ftc_gcache_init( FTC_Cache cache ); - - FT_LOCAL( void ) - ftc_gcache_done( FTC_Cache cache ); - - - FT_LOCAL( FT_Error ) - ftc_cache_init( FTC_Cache cache ); - - FT_LOCAL( void ) - ftc_cache_done( FTC_Cache cache ); - - -#endif /* __FTCCBACK_H__ */ - -/* END */ diff --git a/src/cache/ftccmap.c b/src/cache/ftccmap.c index 02b814818..d0b0b2174 100644 --- a/src/cache/ftccmap.c +++ b/src/cache/ftccmap.c @@ -24,7 +24,6 @@ #include FT_INTERNAL_DEBUG_H #include FT_TRUETYPE_IDS_H -#include "ftccback.h" #include "ftcerror.h" #undef FT_COMPONENT @@ -153,9 +152,9 @@ /* compare a cmap node to a given query */ FT_CALLBACK_DEF( FT_Bool ) - ftc_cmap_node_compare( FTC_Node ftcnode, - FT_Pointer ftcquery, - FTC_Cache cache ) + ftc_cmap_node_equal( FTC_Node ftcnode, + FT_Pointer ftcquery, + FTC_Cache cache ) { FTC_CMapNode node = (FTC_CMapNode)ftcnode; FTC_CMapQuery query = (FTC_CMapQuery)ftcquery; @@ -202,13 +201,13 @@ { ftc_cmap_node_new, ftc_cmap_node_weight, - ftc_cmap_node_compare, + ftc_cmap_node_equal, ftc_cmap_node_remove_faceid, ftc_cmap_node_free, sizeof ( FTC_CacheRec ), - ftc_cache_init, - ftc_cache_done, + FTC_Cache_Init, + FTC_Cache_Done }; @@ -253,7 +252,7 @@ hash = FTC_CMAP_HASH( face_id, cmap_index, char_code ); #if 1 - FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, + FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_equal, hash, &query, node, error ); #else error = FTC_Cache_Lookup( cache, hash, &query, (FTC_Node*) &node ); diff --git a/src/cache/ftcglyph.c b/src/cache/ftcglyph.c index 46d5965b6..2b8fa665c 100644 --- a/src/cache/ftcglyph.c +++ b/src/cache/ftcglyph.c @@ -23,10 +23,17 @@ #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H -#include "ftccback.h" #include "ftcerror.h" + FT_EXPORT_DEF( void ) + FTC_Family_Unref( FTC_Family family ) + { + if ( family && --family->num_nodes <= 0 ) + FTC_GCache_FreeFamily( family->cache, family ); + } + + /* create a new chunk node, setting its cache index and ref count */ FT_EXPORT_DEF( void ) FTC_GNode_Init( FTC_GNode gnode, @@ -40,52 +47,50 @@ FT_EXPORT_DEF( void ) - FTC_GNode_UnselectFamily( FTC_GNode gnode, - FTC_Cache cache ) + FTC_GNode_Done( FTC_GNode gnode ) { FTC_Family family = gnode->family; - - gnode->family = NULL; - if ( family && --family->num_nodes == 0 ) - FTC_FAMILY_FREE( family, cache ); - } - - - FT_EXPORT_DEF( void ) - FTC_GNode_Done( FTC_GNode gnode, - FTC_Cache cache ) - { /* finalize the node */ gnode->gindex = 0; - - FTC_GNode_UnselectFamily( gnode, cache ); - } - - - FT_LOCAL_DEF( FT_Bool ) - ftc_gnode_compare( FTC_Node ftcgnode, - FT_Pointer ftcgquery, - FTC_Cache cache ) - { - FTC_GNode gnode = (FTC_GNode)ftcgnode; - FTC_GQuery gquery = (FTC_GQuery)ftcgquery; - FT_UNUSED( cache ); - - - return FT_BOOL( gnode->family == gquery->family && - gnode->gindex == gquery->gindex ); + gnode->family = 0; + if ( family && --family->num_nodes == 0 ) + FTC_GCache_FreeFamily( family->cache, family ); } FT_EXPORT_DEF( FT_Bool ) - FTC_GNode_Compare( FTC_GNode gnode, - FTC_GQuery gquery ) + FTC_GNode_Equal( FTC_GNode gnode, + FTC_GNode query, + FTC_GCache cache ) { - return ftc_gnode_compare( FTC_NODE( gnode ), gquery, NULL ); + FT_UNUSED(cache); + + return FTC_GNODE_EQUAL(gnode,query,cache); } + FT_EXPORT( FT_Bool ) + FTC_GNode_EqualFaceID( FTC_GNode gnode, + FTC_FaceID face_id, + FTC_GCache cache ) + { + FTC_Family family = gnode->family; + FT_Bool result; + + result = cache->fam_equal_faceid( family, face_id ); + if ( result ) + { + gnode->family = NULL; + if ( family && --family->num_nodes == 0 ) + FTC_GCache_FreeFamily( cache, family ); + } + return result; + } + + + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -94,64 +99,54 @@ /*************************************************************************/ /*************************************************************************/ - FT_EXPORT_DEF( void ) - FTC_Family_Init( FTC_Family family, - FTC_Cache cache ) + FT_EXPORT_DEF( FT_Error ) + FTC_GCache_Init( FTC_GCache cache ) { - FTC_GCacheClass clazz = FTC_CACHE__GCACHE_CLASS( cache ); - - - family->clazz = clazz->family_class; - family->num_nodes = 0; - family->cache = cache; - } - - - FT_LOCAL_DEF( FT_Error ) - ftc_gcache_init( FTC_Cache ftccache ) - { - FTC_GCache cache = (FTC_GCache)ftccache; FT_Error error; error = FTC_Cache_Init( FTC_CACHE( cache ) ); if ( !error ) { - FTC_GCacheClass clazz = (FTC_GCacheClass)FTC_CACHE( cache )->org_class; + FTC_FamilyClass clazz = FTC_GCACHE__FAMILY_CLASS(cache); - FTC_MruList_Init( &cache->families, - clazz->family_class, - 0, /* no maximum here! */ - cache, - FTC_CACHE( cache )->memory ); + cache->families = NULL; + + /* create local copies for better performance */ + cache->fam_equal = clazz->fam_equal; + cache->fam_equal_faceid = clazz->fam_equal_faceid; } return error; } - FT_EXPORT_DEF( FT_Error ) - FTC_GCache_Init( FTC_GCache cache ) - { - return ftc_gcache_init( FTC_CACHE( cache ) ); - } - - - FT_LOCAL_DEF( void ) - ftc_gcache_done( FTC_Cache ftccache ) - { - FTC_GCache cache = (FTC_GCache)ftccache; - - - FTC_Cache_Done( (FTC_Cache)cache ); - FTC_MruList_Done( &cache->families ); - } - - FT_EXPORT_DEF( void ) FTC_GCache_Done( FTC_GCache cache ) { - ftc_gcache_done( FTC_CACHE( cache ) ); + FT_Memory memory = FTC_CACHE__MEMORY(cache); + + FTC_Cache_Done( (FTC_Cache)cache ); + + /* destroy any families that the clients didn't + * release properly !! + */ + if ( cache->families ) + { + FTC_Family family, next; + FTC_FamilyClass clazz = FTC_GCACHE__FAMILY_CLASS(cache); + FTC_Family_DoneFunc family_done = clazz->fam_done; + + for ( family = cache->families; family; family = next ) + { + next = family->link; + + if ( family_done ) + family_done( family ); + + FT_FREE( family ); + } + } } @@ -160,16 +155,146 @@ FTC_GCacheClass clazz, FTC_GCache *acache ) { - return FTC_Manager_RegisterCache( manager, (FTC_CacheClass)clazz, + return FTC_Manager_RegisterCache( manager, + (FTC_CacheClass)clazz, (FTC_Cache*)acache ); } + FT_EXPORT_DEF( void ) + FTC_GCache_FreeFamily( FTC_GCache cache, + FTC_Family family ) + { + FTC_Family* pfamily = &cache->families; + FTC_FamilyClass clazz = FTC_GCACHE__FAMILY_CLASS(cache); + FT_Memory memory = FTC_CACHE__MEMORY(cache); + + for (;;) + { + if ( *pfamily == NULL ) + return; + + if ( *pfamily == family ) + { + *pfamily = family->link; + break; + } + } + + if ( clazz->fam_done ) + clazz->fam_done( family ); + + FT_FREE( family ); + } + + FT_EXPORT_DEF( FT_Error ) + FTC_GCache_NewFamily( FTC_GCache cache, + FT_UInt32 hash, + FTC_Family query, + FTC_Family *afamily ) + { + FT_Memory memory = FTC_CACHE__MEMORY(cache); + FT_Error error; + FTC_Family family; + FTC_FamilyClass clazz = FTC_GCACHE__FAMILY_CLASS(cache); + + if ( !FT_QALLOC( family, clazz->fam_size ) ) + { + FT_MEM_COPY( family, query, clazz->fam_size ); + + family->cache = cache; + family->link = NULL; + family->num_nodes = 0; + family->hash = hash; + + if ( clazz->fam_init ) + { + error = clazz->fam_init( family, query ); + if ( error ) + { + if ( clazz->fam_done ) + clazz->fam_done( family ); + + FT_FREE( family ); + goto Exit; + } + } + + family->link = cache->families; + cache->families = family; + } + + Exit: + *afamily = family; + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FTC_GCache_GetFamily( FTC_GCache cache, + FT_UInt32 hash, + FTC_Family query, + FTC_Family *afamily ) + { + FTC_Family* pfamily = &cache->families; + FTC_Family family; + FTC_Family_EqualFunc fequal = cache->fam_equal; + FT_Error error = 0; + + for (;;) + { + family = *pfamily; + if ( family == NULL ) + break; + + if ( family->hash == hash && fequal( family, query ) ) + { + if ( family != cache->families ) + { + *pfamily = family->link; + family->link = cache->families; + cache->families = family; + } + goto FoundIt; + } + + pfamily = &family->link; + } + + /* we didn't found it */ + error = FTC_GCache_NewFamily( cache, hash, query, &family ); + + FoundIt: + if ( !error ) + family->num_nodes++; + + *afamily = family; + return error; + } + + + FT_EXPORT( FT_Error ) + FTC_GCache_GetNode( FTC_GCache cache, + FT_UInt hash, + FTC_GNode query, + FTC_Node *anode ) + { + FTC_Node node = NULL; + FT_Error error = 0; + + FTC_CACHE_LOOKUP_CMP( cache, FTC_CACHE(cache)->node_equal, hash, + query, node, error ); + + *anode = node; + return error; + } + +#if 0 FT_EXPORT_DEF( FT_Error ) FTC_GCache_Lookup( FTC_GCache cache, FT_UInt32 hash, FT_UInt gindex, - FTC_GQuery query, + FTC_GNode query, FTC_Node *anode ) { FT_Error error; @@ -177,12 +302,14 @@ query->gindex = gindex; - FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error ); + FTC_MRULIST_LOOKUP( &cache->families, + query->family, + query->family, + error ); if ( !error ) { FTC_Family family = query->family; - /* prevent the family from being destroyed too early when an */ /* out-of-memory condition occurs during glyph node initialization. */ family->num_nodes++; @@ -194,6 +321,7 @@ } return error; } +#endif /* END */ diff --git a/src/cache/ftcimage.c b/src/cache/ftcimage.c index 02020bac3..b7d6cdfcb 100644 --- a/src/cache/ftcimage.c +++ b/src/cache/ftcimage.c @@ -21,17 +21,15 @@ #include FT_CACHE_INTERNAL_IMAGE_H #include FT_INTERNAL_MEMORY_H -#include "ftccback.h" #include "ftcerror.h" /* finalize a given glyph image node */ - FT_LOCAL_DEF( void ) - ftc_inode_free( FTC_Node ftcinode, - FTC_Cache cache ) + FT_EXPORT_DEF( void ) + FTC_INode_Free( FTC_INode inode, + FTC_GCache cache ) { - FTC_INode inode = (FTC_INode)ftcinode; - FT_Memory memory = cache->memory; + FT_Memory memory = FTC_CACHE__MEMORY(cache); if ( inode->glyph ) @@ -40,26 +38,18 @@ inode->glyph = NULL; } - FTC_GNode_Done( FTC_GNODE( inode ), cache ); + FTC_GNode_Done( FTC_GNODE( inode ) ); FT_FREE( inode ); } - FT_EXPORT_DEF( void ) - FTC_INode_Free( FTC_INode inode, - FTC_Cache cache ) - { - ftc_inode_free( FTC_NODE( inode ), cache ); - } - - /* initialize a new glyph image node */ FT_EXPORT_DEF( FT_Error ) FTC_INode_New( FTC_INode *pinode, - FTC_GQuery gquery, - FTC_Cache cache ) + FTC_GNode gquery, + FTC_GCache cache ) { - FT_Memory memory = cache->memory; + FT_Memory memory = FTC_CACHE__MEMORY(cache); FT_Error error; FTC_INode inode; @@ -69,15 +59,16 @@ FTC_GNode gnode = FTC_GNODE( inode ); FTC_Family family = gquery->family; FT_UInt gindex = gquery->gindex; - FTC_IFamilyClass clazz = FTC_CACHE__IFAMILY_CLASS( cache ); + FTC_ICacheClass clazz = FTC_ICACHE__CLASS( cache ); /* initialize its inner fields */ FTC_GNode_Init( gnode, gindex, family ); /* we will now load the glyph image */ - error = clazz->family_load_glyph( family, gindex, cache, - &inode->glyph ); + error = clazz->fam_load_glyph( family, gindex, + FTC_CACHE__MANAGER(cache), + &inode->glyph ); if ( error ) { FTC_INode_Free( inode, cache ); @@ -90,29 +81,13 @@ } - FT_LOCAL_DEF( FT_Error ) - ftc_inode_new( FTC_Node *ftcpinode, - FT_Pointer ftcgquery, - FTC_Cache cache ) + + FT_EXPORT_DEF( FT_ULong ) + FTC_INode_Weight( FTC_INode inode ) { - FTC_INode *pinode = (FTC_INode*)ftcpinode; - FTC_GQuery gquery = (FTC_GQuery)ftcgquery; - - - return FTC_INode_New( pinode, gquery, cache ); - } - - - FT_LOCAL_DEF( FT_ULong ) - ftc_inode_weight( FTC_Node ftcinode, - FTC_Cache ftccache ) - { - FTC_INode inode = (FTC_INode)ftcinode; FT_ULong size = 0; FT_Glyph glyph = inode->glyph; - FT_UNUSED( ftccache ); - switch ( glyph->format ) { @@ -149,11 +124,4 @@ } - FT_EXPORT_DEF( FT_ULong ) - FTC_INode_Weight( FTC_INode inode ) - { - return ftc_inode_weight( FTC_NODE( inode ), NULL ); - } - - /* END */ diff --git a/src/cache/ftcmanag.c b/src/cache/ftcmanag.c index 337bea5f9..356e42718 100644 --- a/src/cache/ftcmanag.c +++ b/src/cache/ftcmanag.c @@ -93,7 +93,7 @@ FT_CALLBACK_DEF( FT_Bool ) - ftc_size_node_compare( FTC_MruNode ftcnode, + ftc_size_node_equal( FTC_MruNode ftcnode, FT_Pointer ftcscaler ) { FTC_SizeNode node = (FTC_SizeNode)ftcnode; @@ -148,7 +148,7 @@ const FTC_MruListClassRec ftc_size_list_class = { sizeof ( FTC_SizeNodeRec ), - ftc_size_node_compare, + ftc_size_node_equal, ftc_size_node_init, ftc_size_node_reset, ftc_size_node_done @@ -157,7 +157,7 @@ /* helper function used by ftc_face_node_done */ static FT_Bool - ftc_size_node_compare_faceid( FTC_MruNode ftcnode, + ftc_size_node_equal_faceid( FTC_MruNode ftcnode, FT_Pointer ftcface_id ) { FTC_SizeNode node = (FTC_SizeNode)ftcnode; @@ -189,7 +189,7 @@ #ifdef FTC_INLINE - FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_compare, + FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_equal, node, error ); #else @@ -259,7 +259,7 @@ /* we must begin by removing all scalers for the target face */ /* from the manager's list */ FTC_MruList_RemoveSelection( &manager->sizes, - ftc_size_node_compare_faceid, + ftc_size_node_equal_faceid, node->face_id ); /* all right, we can discard the face now */ @@ -270,7 +270,7 @@ FT_CALLBACK_DEF( FT_Bool ) - ftc_face_node_compare( FTC_MruNode ftcnode, + ftc_face_node_equal( FTC_MruNode ftcnode, FT_Pointer ftcface_id ) { FTC_FaceNode node = (FTC_FaceNode)ftcnode; @@ -286,7 +286,7 @@ { sizeof ( FTC_FaceNodeRec), - ftc_face_node_compare, + ftc_face_node_equal, ftc_face_node_init, 0, /* FTC_MruNode_ResetFunc */ ftc_face_node_done @@ -315,7 +315,7 @@ /* we break encapsulation for the sake of speed */ #ifdef FTC_INLINE - FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_compare, + FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_equal, node, error ); #else @@ -419,7 +419,7 @@ if ( cache ) { - cache->clazz.cache_done( cache ); + cache->clazz->cache_done( cache ); FT_FREE( cache ); manager->caches[idx] = NULL; } @@ -478,7 +478,7 @@ FT_ERROR(( "FTC_Manager_Check: invalid node (cache index = %ld\n", node->cache_index )); else - weight += cache->clazz.node_weight( node, cache ); + weight += cache->node_weight( node, cache ); node = FTC_NODE__NEXT( node ); @@ -585,10 +585,11 @@ if ( !FT_ALLOC( cache, clazz->cache_size ) ) { - cache->manager = manager; - cache->memory = memory; - cache->clazz = clazz[0]; - cache->org_class = clazz; + cache->manager = manager; + cache->memory = memory; + cache->node_equal = clazz->node_equal; + cache->node_weight = clazz->node_weight; + cache->clazz = clazz; /* THIS IS VERY IMPORTANT! IT WILL WRETCH THE MANAGER */ /* IF IT IS NOT SET CORRECTLY */ diff --git a/src/cache/ftcmru.c b/src/cache/ftcmru.c index d4f733a11..a455848c5 100644 --- a/src/cache/ftcmru.c +++ b/src/cache/ftcmru.c @@ -202,7 +202,7 @@ FTC_MruList_Find( FTC_MruList list, FT_Pointer key ) { - FTC_MruNode_CompareFunc compare = list->clazz.node_compare; + FTC_MruNode_EqualFunc compare = list->clazz.node_equal; FTC_MruNode first, node; @@ -323,7 +323,7 @@ FT_EXPORT_DEF( void ) FTC_MruList_RemoveSelection( FTC_MruList list, - FTC_MruNode_CompareFunc selection, + FTC_MruNode_EqualFunc selection, FT_Pointer key ) { FTC_MruNode first, node, next; diff --git a/src/cache/ftcsbits.c b/src/cache/ftcsbits.c index 891c7ab8e..4e8922ab0 100644 --- a/src/cache/ftcsbits.c +++ b/src/cache/ftcsbits.c @@ -23,7 +23,6 @@ #include FT_INTERNAL_DEBUG_H #include FT_ERRORS_H -#include "ftccback.h" #include "ftcerror.h" @@ -58,33 +57,24 @@ } - FT_LOCAL_DEF( void ) - ftc_snode_free( FTC_Node ftcsnode, - FTC_Cache cache ) + FT_EXPORT_DEF( void ) + FTC_SNode_Free( FTC_SNode snode, + FTC_GCache cache ) { - FTC_SNode snode = (FTC_SNode)ftcsnode; FTC_SBit sbit = snode->sbits; FT_UInt count = snode->count; - FT_Memory memory = cache->memory; + FT_Memory memory = FTC_CACHE__MEMORY(cache); for ( ; count > 0; sbit++, count-- ) FT_FREE( sbit->buffer ); - FTC_GNode_Done( FTC_GNODE( snode ), cache ); + FTC_GNode_Done( FTC_GNODE( snode ) ); FT_FREE( snode ); } - FT_EXPORT_DEF( void ) - FTC_SNode_Free( FTC_SNode snode, - FTC_Cache cache ) - { - ftc_snode_free( FTC_NODE( snode ), cache ); - } - - /* * This function tries to load a small bitmap within a given FTC_SNode. * Note that it returns a non-zero error code _only_ in the case of @@ -92,7 +82,7 @@ * to a bad font file), this function will mark the sbit as `unavailable' * and return a value of 0. * - * You should also read the comment within the @ftc_snode_compare + * You should also read the comment within the @ftc_snode_equal * function below to see how out-of-memory is handled during a lookup. */ static FT_Error @@ -107,7 +97,7 @@ FT_Memory memory = manager->memory; FT_Face face; FTC_SBit sbit; - FTC_SFamilyClass clazz; + FTC_SCacheClass clazz; if ( (FT_UInt)(gindex - gnode->gindex) >= snode->count ) @@ -117,11 +107,11 @@ } sbit = snode->sbits + ( gindex - gnode->gindex ); - clazz = (FTC_SFamilyClass)family->clazz; + clazz = FTC_SCACHE__CLASS(FTC_FAMILY__CACHE(family)); sbit->buffer = 0; - error = clazz->family_load_glyph( family, gindex, manager, &face ); + error = clazz->fam_load_glyph( family, gindex, manager, &face ); if ( error ) goto BadGlyph; @@ -199,20 +189,20 @@ FT_EXPORT_DEF( FT_Error ) FTC_SNode_New( FTC_SNode *psnode, - FTC_GQuery gquery, - FTC_Cache cache ) + FTC_GNode gquery, + FTC_GCache cache ) { - FT_Memory memory = cache->memory; + FT_Memory memory = FTC_CACHE__MEMORY(cache); FT_Error error; FTC_SNode snode = NULL; FT_UInt gindex = gquery->gindex; FTC_Family family = gquery->family; - FTC_SFamilyClass clazz = FTC_CACHE__SFAMILY_CLASS( cache ); + FTC_SCacheClass clazz = FTC_SCACHE__CLASS(cache); FT_UInt total; - total = clazz->family_get_count( family, cache->manager ); + total = clazz->fam_get_count( family, FTC_CACHE__MANAGER(cache) ); if ( total == 0 || gindex >= total ) { error = FT_Err_Invalid_Argument; @@ -234,7 +224,7 @@ snode->count = count; error = ftc_snode_load( snode, - cache->manager, + FTC_CACHE__MANAGER(cache), gindex, NULL ); if ( error ) @@ -250,32 +240,16 @@ } - FT_LOCAL_DEF( FT_Error ) - ftc_snode_new( FTC_Node *ftcpsnode, - FT_Pointer ftcgquery, - FTC_Cache cache ) + + + FT_EXPORT_DEF( FT_ULong ) + FTC_SNode_Weight( FTC_SNode snode ) { - FTC_SNode *psnode = (FTC_SNode*)ftcpsnode; - FTC_GQuery gquery = (FTC_GQuery)ftcgquery; - - - return FTC_SNode_New( psnode, gquery, cache ); - } - - - FT_LOCAL_DEF( FT_ULong ) - ftc_snode_weight( FTC_Node ftcsnode, - FTC_Cache cache ) - { - FTC_SNode snode = (FTC_SNode)ftcsnode; FT_UInt count = snode->count; FTC_SBit sbit = snode->sbits; FT_Int pitch; FT_ULong size; - FT_UNUSED( cache ); - - FT_ASSERT( snode->count <= FTC_SBIT_ITEMS_PER_NODE ); /* the node itself */ @@ -298,20 +272,11 @@ } - FT_EXPORT_DEF( FT_ULong ) - FTC_SNode_Weight( FTC_SNode snode ) + FT_EXPORT_DEF( FT_Bool ) + FTC_SNode_Equal( FTC_SNode snode, + FTC_GNode gquery, + FTC_Cache cache ) { - return ftc_snode_weight( FTC_NODE( snode ), NULL ); - } - - - FT_LOCAL_DEF( FT_Bool ) - ftc_snode_compare( FTC_Node ftcsnode, - FT_Pointer ftcgquery, - FTC_Cache cache ) - { - FTC_SNode snode = (FTC_SNode)ftcsnode; - FTC_GQuery gquery = (FTC_GQuery)ftcgquery; FTC_GNode gnode = FTC_GNODE( snode ); FT_UInt gindex = gquery->gindex; FT_Bool result; @@ -341,7 +306,7 @@ * However, we need to `lock' the node before this operation to * prevent it from being flushed within the loop. * - * When we exit the loop, we unlock the node, then check the `error' + * When we exit the loop, we unlock the node, then check the `error' * variable. If it is non-zero, this means that the cache was * completely flushed and that no usable memory was found to load * the bitmap. @@ -363,8 +328,8 @@ FT_Error error; - ftcsnode->ref_count++; /* lock node to prevent flushing */ - /* in retry loop */ + FTC_NODE_REF(snode); /* lock node to prevent flushing */ + /* in retry loop */ FTC_CACHE_TRYLOOP( cache ) { @@ -372,7 +337,7 @@ } FTC_CACHE_TRYLOOP_END(); - ftcsnode->ref_count--; /* unlock the node */ + FTC_NODE(snode)->ref_count--; /* unlock the node */ if ( error ) result = 0; @@ -385,13 +350,6 @@ } - FT_EXPORT_DEF( FT_Bool ) - FTC_SNode_Compare( FTC_SNode snode, - FTC_GQuery gquery, - FTC_Cache cache ) - { - return ftc_snode_compare( FTC_NODE( snode ), gquery, cache ); - } /* END */