summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Turner <david@freetype.org>2005-09-21 23:22:03 +0000
committerDavid Turner <david@freetype.org>2005-09-21 23:22:03 +0000
commitb260500eac1fcca24b70ce565cd8bb4fe91bb266 (patch)
treed2a80ef660687af13b00f5a40658f554afef8f32
parentb5bf91c5dd37191bd8c29b922366271413752197 (diff)
downloadfreetype2-b260500eac1fcca24b70ce565cd8bb4fe91bb266.tar.gz
* 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)
-rw-r--r--ChangeLog7
-rw-r--r--include/freetype/cache/ftccache.h63
-rw-r--r--include/freetype/cache/ftcglyph.h249
-rw-r--r--include/freetype/cache/ftcimage.h46
-rw-r--r--include/freetype/cache/ftcmru.h50
-rw-r--r--include/freetype/cache/ftcsbits.h50
-rw-r--r--include/freetype/ftcache.h191
-rw-r--r--src/cache/ftcbasic.c386
-rw-r--r--src/cache/ftccache.c40
-rw-r--r--src/cache/ftccback.h85
-rw-r--r--src/cache/ftccmap.c15
-rw-r--r--src/cache/ftcglyph.c264
-rw-r--r--src/cache/ftcimage.c60
-rw-r--r--src/cache/ftcmanag.c29
-rw-r--r--src/cache/ftcmru.c4
-rw-r--r--src/cache/ftcsbits.c92
16 files changed, 905 insertions, 726 deletions
diff --git a/ChangeLog b/ChangeLog
index 95d619a12..6fdcc8fe8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
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 <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 );
+
+ /* used by FTC_GCACHE_GET_FAMILY, don't call directly */
FT_EXPORT( FT_Error )
- FTC_GCache_Lookup( FTC_GCache cache,
- FT_UInt32 hash,
- FT_UInt gindex,
- FTC_GQuery query,
- FTC_Node *anode );
+ 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 );
-#define FTC_FAMILY_FREE( family, cache ) \
- FTC_MruList_Remove( &FTC_GCACHE((cache))->families, \
- (FTC_MruNode)(family) )
+ /* 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 );
+
+ /* */
#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_ICacheClassRec;
- } FTC_IFamilyClassRec;
+ typedef const FTC_ICacheClassRec* FTC_ICacheClass;
- typedef const FTC_IFamilyClassRec* FTC_IFamilyClass;
+#define FTC_ICACHE_CLASS(x) ((FTC_ICacheClass)(x))
-#define FTC_IFAMILY_CLASS( x ) ((FTC_IFamilyClass)(x))
+#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_CACHE__IFAMILY_CLASS( x ) \
- FTC_IFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS(x)->family_class )
+#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_SCacheClassRec;
+
+ typedef const FTC_SCacheClassRec* FTC_SCacheClass;
- } FTC_SFamilyClassRec;
+#define FTC_SCACHE_CLASS(x) ((FTC_SCacheClass)(x))
+#define FTC_SCACHE__CLASS(c) FTC_SCACHE_CLASS(FTC_CACHE__CLASS(c))
- typedef const FTC_SFamilyClassRec* FTC_SFamilyClass;
+#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
@@ -248,6 +248,21 @@ FT_BEGIN_HEADER
/*************************************************************************/
/* */
+ /* <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> */
/* FTC_Manager_New */
/* */
@@ -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 );
/* */
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;
- FT_CALLBACK_DEF( FT_Bool )
- ftc_basic_family_compare( FTC_MruNode ftcfamily,
- FT_Pointer ftcquery )
- {
- FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
- FTC_BasicQuery query = (FTC_BasicQuery)ftcquery;
+#define FTC_BASIC_FAMILY_HASH(f) \
+ ( FTC_SCALER_HASH( &(f)->scaler ) + 31*(f)->load_flags )
- return FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs );
+ FT_CALLBACK_DEF( FT_Bool )
+ ftc_basic_family_equal( FTC_BasicFamily family,
+ FTC_BasicFamily query )
+ {
+ 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;
-
- query.attrs.scaler.x_res = 0; /* make compilers happy */
- query.attrs.scaler.y_res = 0;
-
- 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
+ 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;
+
+ hash = FTC_BASIC_FAMILY_HASH( &key_family );
+
+ 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;
-
- query.attrs.scaler.x_res = 0; /* make compilers happy */
- query.attrs.scaler.y_res = 0;
-
- /* 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;
+ 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;
- *ansbit = node->sbits + ( gindex - FTC_GNODE( node )->gindex );
+ hash = FTC_BASIC_FAMILY_HASH( &key_family );
- 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 :-) */
@@ -304,13 +303,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 <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 */
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,50 +47,48 @@
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;
+ /* finalize the node */
+ gnode->gindex = 0;
+ gnode->family = 0;
if ( family && --family->num_nodes == 0 )
- FTC_FAMILY_FREE( family, cache );
+ FTC_GCache_FreeFamily( family->cache, family );
}
- FT_EXPORT_DEF( void )
- FTC_GNode_Done( FTC_GNode gnode,
- FTC_Cache cache )
+ FT_EXPORT_DEF( FT_Bool )
+ FTC_GNode_Equal( FTC_GNode gnode,
+ FTC_GNode query,
+ FTC_GCache cache )
{
- /* finalize the node */
- gnode->gindex = 0;
+ FT_UNUSED(cache);
- FTC_GNode_UnselectFamily( gnode, cache );
+ return FTC_GNODE_EQUAL(gnode,query,cache);
}
- FT_LOCAL_DEF( FT_Bool )
- ftc_gnode_compare( FTC_Node ftcgnode,
- FT_Pointer ftcgquery,
- FTC_Cache cache )
+ FT_EXPORT( FT_Bool )
+ FTC_GNode_EqualFaceID( FTC_GNode gnode,
+ FTC_FaceID face_id,
+ FTC_GCache cache )
{
- FTC_GNode gnode = (FTC_GNode)ftcgnode;
- FTC_GQuery gquery = (FTC_GQuery)ftcgquery;
- FT_UNUSED( cache );
-
+ FTC_Family family = gnode->family;
+ FT_Bool result;
- return FT_BOOL( gnode->family == gquery->family &&
- gnode->gindex == gquery->gindex );
+ 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;
}
- FT_EXPORT_DEF( FT_Bool )
- FTC_GNode_Compare( FTC_GNode gnode,
- FTC_GQuery gquery )
- {
- return ftc_gnode_compare( FTC_NODE( gnode ), gquery, NULL );
- }
/*************************************************************************/
@@ -94,82 +99,202 @@
/*************************************************************************/
/*************************************************************************/
- 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 );
+ FT_Error error;
+
+
+ error = FTC_Cache_Init( FTC_CACHE( cache ) );
+ if ( !error )
+ {
+ FTC_FamilyClass clazz = FTC_GCACHE__FAMILY_CLASS(cache);
+ cache->families = NULL;
+
+ /* create local copies for better performance */
+ cache->fam_equal = clazz->fam_equal;
+ cache->fam_equal_faceid = clazz->fam_equal_faceid;
+ }
- family->clazz = clazz->family_class;
- family->num_nodes = 0;
- family->cache = cache;
+ return error;
}
- FT_LOCAL_DEF( FT_Error )
- ftc_gcache_init( FTC_Cache ftccache )
+ FT_EXPORT_DEF( void )
+ FTC_GCache_Done( FTC_GCache cache )
{
- FTC_GCache cache = (FTC_GCache)ftccache;
- FT_Error error;
+ FT_Memory memory = FTC_CACHE__MEMORY(cache);
+ FTC_Cache_Done( (FTC_Cache)cache );
- error = FTC_Cache_Init( FTC_CACHE( cache ) );
- if ( !error )
+ /* destroy any families that the clients didn't
+ * release properly !!
+ */
+ if ( cache->families )
{
- FTC_GCacheClass clazz = (FTC_GCacheClass)FTC_CACHE( cache )->org_class;
+ FTC_Family family, next;
+ FTC_FamilyClass clazz = FTC_GCACHE__FAMILY_CLASS(cache);
+ FTC_Family_DoneFunc family_done = clazz->fam_done;
- FTC_MruList_Init( &cache->families,
- clazz->family_class,
- 0, /* no maximum here! */
- cache,
- FTC_CACHE( cache )->memory );
- }
+ for ( family = cache->families; family; family = next )
+ {
+ next = family->link;
- return error;
+ if ( family_done )
+ family_done( family );
+
+ FT_FREE( family );
+ }
+ }
}
FT_EXPORT_DEF( FT_Error )
- FTC_GCache_Init( FTC_GCache cache )
+ FTC_GCache_New( FTC_Manager manager,
+ FTC_GCacheClass clazz,
+ FTC_GCache *acache )
{
- return ftc_gcache_init( FTC_CACHE( cache ) );
+ return FTC_Manager_RegisterCache( manager,
+ (FTC_CacheClass)clazz,
+ (FTC_Cache*)acache );
}
- FT_LOCAL_DEF( void )
- ftc_gcache_done( FTC_Cache ftccache )
+ FT_EXPORT_DEF( void )
+ FTC_GCache_FreeFamily( FTC_GCache cache,
+ FTC_Family family )
{
- FTC_GCache cache = (FTC_GCache)ftccache;
+ 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;
+ }
+ }
- FTC_Cache_Done( (FTC_Cache)cache );
- FTC_MruList_Done( &cache->families );
- }
+ if ( clazz->fam_done )
+ clazz->fam_done( family );
+ FT_FREE( family );
+ }
- FT_EXPORT_DEF( void )
- FTC_GCache_Done( FTC_GCache cache )
+ FT_EXPORT_DEF( FT_Error )
+ FTC_GCache_NewFamily( FTC_GCache cache,
+ FT_UInt32 hash,
+ FTC_Family query,
+ FTC_Family *afamily )
{
- ftc_gcache_done( FTC_CACHE( cache ) );
+ 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_New( FTC_Manager manager,
- FTC_GCacheClass clazz,
- FTC_GCache *acache )
+ FTC_GCache_GetFamily( FTC_GCache cache,
+ FT_UInt32 hash,
+ FTC_Family query,
+ FTC_Family *afamily )
{
- return FTC_Manager_RegisterCache( manager, (FTC_CacheClass)clazz,
- (FTC_Cache*)acache );
+ 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 )
- {
- 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 )
+ FT_EXPORT_DEF( FT_ULong )
+ FTC_INode_Weight( FTC_INode inode )
{
- 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 )
- {
- 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 )
+ FT_EXPORT_DEF( FT_ULong )
+ FTC_SNode_Weight( FTC_SNode snode )
{
- 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 )
- {
- 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 )
+ FT_EXPORT_DEF( FT_Bool )
+ FTC_SNode_Equal( FTC_SNode snode,
+ FTC_GNode gquery,
+ 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 */