* 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)
This commit is contained in:
David Turner 2005-09-21 23:22:03 +00:00
parent b5bf91c5dd
commit b260500eac
16 changed files with 919 additions and 740 deletions

View File

@ -1,3 +1,10 @@
2005-09-21 David Turner <david@freetype.org>
* 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 <dsomers@omz13.com>
* freetype2/src/sfnt/ttload.c (sfnt_dir_check): Modified to allow a

View File

@ -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:
*
* {

View File

@ -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 <ft2build.h>
#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 */

View File

@ -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 )

View File

@ -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

View File

@ -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

View File

@ -246,6 +246,21 @@ FT_BEGIN_HEADER
typedef struct FTC_NodeRec_* FTC_Node;
/*************************************************************************/
/* */
/* <Type> */
/* FTC_Family */
/* */
/* <Description> */
/* 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;
/*************************************************************************/
/* */
/* <Function> */
@ -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)
/*************************************************************************/
/* */
/* <Section> */
@ -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 );
/*************************************************************************/
/* */
/* <Type> */
@ -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 );
/* */

382
src/cache/ftcbasic.c vendored
View File

@ -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 */

40
src/cache/ftccache.c vendored
View File

@ -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++;
}

85
src/cache/ftccback.h vendored
View File

@ -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 <ft2build.h>
#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 */

15
src/cache/ftccmap.c vendored
View File

@ -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 );

286
src/cache/ftcglyph.c vendored
View File

@ -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 */

62
src/cache/ftcimage.c vendored
View File

@ -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 */

29
src/cache/ftcmanag.c vendored
View File

@ -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 */

4
src/cache/ftcmru.c vendored
View File

@ -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;

96
src/cache/ftcsbits.c vendored
View File

@ -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 */