important bug fixes for new cache code
This commit is contained in:
parent
32174ffba2
commit
89f331b713
|
@ -19,7 +19,7 @@
|
||||||
#ifndef __FTCCACHE_H__
|
#ifndef __FTCCACHE_H__
|
||||||
#define __FTCCACHE_H__
|
#define __FTCCACHE_H__
|
||||||
|
|
||||||
|
#include FT_CACHE_INTERNAL_MRU_H
|
||||||
|
|
||||||
FT_BEGIN_HEADER
|
FT_BEGIN_HEADER
|
||||||
|
|
||||||
|
@ -52,8 +52,7 @@ FT_BEGIN_HEADER
|
||||||
/* structure size should be 20 bytes on 32-bits machines */
|
/* structure size should be 20 bytes on 32-bits machines */
|
||||||
typedef struct FTC_NodeRec_
|
typedef struct FTC_NodeRec_
|
||||||
{
|
{
|
||||||
FTC_Node mru_next; /* circular mru list pointer */
|
FTC_MruNodeRec mru; /* circular mru list pointer */
|
||||||
FTC_Node mru_prev; /* circular mru list pointer */
|
|
||||||
FTC_Node link; /* used for hashing */
|
FTC_Node link; /* used for hashing */
|
||||||
FT_UInt32 hash; /* used for hashing too */
|
FT_UInt32 hash; /* used for hashing too */
|
||||||
FT_UShort cache_index; /* index of cache the node belongs to */
|
FT_UShort cache_index; /* index of cache the node belongs to */
|
||||||
|
@ -65,6 +64,8 @@ FT_BEGIN_HEADER
|
||||||
#define FTC_NODE( x ) ( (FTC_Node)(x) )
|
#define FTC_NODE( x ) ( (FTC_Node)(x) )
|
||||||
#define FTC_NODE_P( x ) ( (FTC_Node*)(x) )
|
#define FTC_NODE_P( x ) ( (FTC_Node*)(x) )
|
||||||
|
|
||||||
|
#define FTC_NODE__MRU_NEXT(x) FTC_NODE( (x)->mru.next )
|
||||||
|
#define FTC_NODE__MRU_PREV(x) FTC_NODE( (x)->mru.prev )
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
|
|
|
@ -133,8 +133,9 @@ FT_BEGIN_HEADER
|
||||||
|
|
||||||
typedef struct FTC_FamilyRec_
|
typedef struct FTC_FamilyRec_
|
||||||
{
|
{
|
||||||
FTC_MruNode mrunode;
|
FTC_MruNodeRec mrunode;
|
||||||
FT_UInt num_nodes; /* current number of nodes in this family */
|
FT_UInt num_nodes; /* current number of nodes in this family */
|
||||||
|
FTC_Cache cache;
|
||||||
FTC_MruListClass clazz;
|
FTC_MruListClass clazz;
|
||||||
|
|
||||||
} FTC_FamilyRec, *FTC_Family;
|
} FTC_FamilyRec, *FTC_Family;
|
||||||
|
@ -166,15 +167,6 @@ FT_BEGIN_HEADER
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* each glyph node contains a 'chunk' of glyph items; */
|
|
||||||
/* translate a glyph index into a chunk index */
|
|
||||||
#define FTC_FAMILY_CHUNK( gfam, gindex ) \
|
|
||||||
( ( gindex ) / FTC_FAMILY( gfam )->item_count )
|
|
||||||
|
|
||||||
/* find a glyph index's chunk, and return its start index */
|
|
||||||
#define FTC_FAMILY_START( gfam, gindex ) \
|
|
||||||
( FTC_FAMILY_CHUNK( gfam, gindex ) * \
|
|
||||||
FTC_FAMILY( gfam )->item_count )
|
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
|
@ -209,6 +201,10 @@ FT_BEGIN_HEADER
|
||||||
FTC_Cache cache );
|
FTC_Cache cache );
|
||||||
|
|
||||||
|
|
||||||
|
FT_EXPORT( void )
|
||||||
|
FTC_Family_Init( FTC_Family family,
|
||||||
|
FTC_Cache cache );
|
||||||
|
|
||||||
typedef struct FTC_GCacheRec_
|
typedef struct FTC_GCacheRec_
|
||||||
{
|
{
|
||||||
FTC_CacheRec cache;
|
FTC_CacheRec cache;
|
||||||
|
@ -243,6 +239,7 @@ FT_BEGIN_HEADER
|
||||||
#define FTC_GCACHE_CLASS(x) ((FTC_GCacheClass)(x))
|
#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__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)
|
||||||
|
|
||||||
|
|
||||||
/* convenience function. use instead of FTC_Manager_Register_Cache */
|
/* convenience function. use instead of FTC_Manager_Register_Cache */
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
|
|
||||||
FT_BEGIN_HEADER
|
FT_BEGIN_HEADER
|
||||||
|
|
||||||
|
#define FT_DEBUG_ERROR
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
|
@ -174,7 +175,7 @@ FT_BEGIN_HEADER
|
||||||
#define FTC_SCALER_HASH(q) \
|
#define FTC_SCALER_HASH(q) \
|
||||||
( FTC_FACE_ID_HASH((q)->face_id) + \
|
( FTC_FACE_ID_HASH((q)->face_id) + \
|
||||||
(q)->width + (q)->height*7 + \
|
(q)->width + (q)->height*7 + \
|
||||||
(q)->pixel ? ( (q)->x_res*33 ^ (q)->y_res*61 ) : 0 )
|
( (q)->pixel ? 0 : ( (q)->x_res*33 ^ (q)->y_res*61 ) ) )
|
||||||
|
|
||||||
|
|
||||||
FT_EXPORT( FT_Error )
|
FT_EXPORT( FT_Error )
|
||||||
|
|
|
@ -56,18 +56,33 @@
|
||||||
|
|
||||||
FT_BEGIN_HEADER
|
FT_BEGIN_HEADER
|
||||||
|
|
||||||
typedef struct FTC_MruListRec_* FTC_MruList;
|
|
||||||
|
|
||||||
typedef struct FTC_MruNodeRec_* FTC_MruNode;
|
typedef struct FTC_MruNodeRec_* FTC_MruNode;
|
||||||
|
|
||||||
typedef struct FTC_MruListClassRec_ const * FTC_MruListClass;
|
|
||||||
|
|
||||||
typedef struct FTC_MruNodeRec_
|
typedef struct FTC_MruNodeRec_
|
||||||
{
|
{
|
||||||
FTC_MruNode next;
|
FTC_MruNode next;
|
||||||
|
FTC_MruNode prev;
|
||||||
|
|
||||||
} FTC_MruNodeRec;
|
} FTC_MruNodeRec;
|
||||||
|
|
||||||
|
|
||||||
|
FT_EXPORT( void )
|
||||||
|
FTC_MruNode_Prepend( FTC_MruNode *plist,
|
||||||
|
FTC_MruNode node );
|
||||||
|
|
||||||
|
FT_EXPORT( void )
|
||||||
|
FTC_MruNode_Up( FTC_MruNode *plist,
|
||||||
|
FTC_MruNode node );
|
||||||
|
|
||||||
|
FT_EXPORT( void )
|
||||||
|
FTC_MruNode_Remove( FTC_MruNode *plist,
|
||||||
|
FTC_MruNode node );
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct FTC_MruListRec_* FTC_MruList;
|
||||||
|
|
||||||
|
typedef struct FTC_MruListClassRec_ const * FTC_MruListClass;
|
||||||
|
|
||||||
typedef FT_Int (*FTC_MruNode_CompareFunc)( FTC_MruNode node,
|
typedef FT_Int (*FTC_MruNode_CompareFunc)( FTC_MruNode node,
|
||||||
FT_Pointer key );
|
FT_Pointer key );
|
||||||
|
|
||||||
|
@ -92,6 +107,7 @@ FT_BEGIN_HEADER
|
||||||
|
|
||||||
} FTC_MruListClassRec;
|
} FTC_MruListClassRec;
|
||||||
|
|
||||||
|
|
||||||
typedef struct FTC_MruListRec_
|
typedef struct FTC_MruListRec_
|
||||||
{
|
{
|
||||||
FT_UInt num_nodes;
|
FT_UInt num_nodes;
|
||||||
|
@ -119,10 +135,18 @@ FT_BEGIN_HEADER
|
||||||
FTC_MruList_Done( FTC_MruList list );
|
FTC_MruList_Done( FTC_MruList list );
|
||||||
|
|
||||||
|
|
||||||
FT_EXPORT( FT_Error )
|
FT_EXPORT( FTC_MruNode )
|
||||||
FTC_MruList_Lookup( FTC_MruList list,
|
FTC_MruList_Lookup( FTC_MruList list,
|
||||||
|
FT_Pointer key );
|
||||||
|
|
||||||
|
FT_EXPORT( void )
|
||||||
|
FTC_MruList_Up( FTC_MruList list,
|
||||||
|
FTC_MruNode node );
|
||||||
|
|
||||||
|
FT_EXPORT( FT_Error )
|
||||||
|
FTC_MruList_New( FTC_MruList list,
|
||||||
FT_Pointer key,
|
FT_Pointer key,
|
||||||
FTC_MruNode *pnode );
|
FTC_MruNode *anode );
|
||||||
|
|
||||||
FT_EXPORT( void )
|
FT_EXPORT( void )
|
||||||
FTC_MruList_Remove( FTC_MruList list,
|
FTC_MruList_Remove( FTC_MruList list,
|
||||||
|
|
|
@ -20,7 +20,7 @@ OBJS=ftcache.obj
|
||||||
all : $(OBJS)
|
all : $(OBJS)
|
||||||
library [--.lib]freetype.olb $(OBJS)
|
library [--.lib]freetype.olb $(OBJS)
|
||||||
|
|
||||||
ftcache.obj : ftcache.c ftlru.c ftcmanag.c ftccache.c ftcglyph.c ftcimage.c \
|
ftcache.obj : ftcache.c ftcmru.c ftcmanag.c ftccache.c ftcglyph.c ftcimage.c \
|
||||||
ftcsbits.c ftccmap.c
|
ftcsbits.c ftccmap.c ftcbasic.c
|
||||||
|
|
||||||
# EOF
|
# EOF
|
||||||
|
|
|
@ -57,15 +57,7 @@
|
||||||
FTC_BasicQuery query,
|
FTC_BasicQuery query,
|
||||||
FTC_Cache cache )
|
FTC_Cache cache )
|
||||||
{
|
{
|
||||||
ftc_family_init( FTC_FAMILY( family ), cache );
|
FTC_Family_Init( FTC_FAMILY( family ), cache );
|
||||||
family->attrs = query->attrs;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FT_Error
|
|
||||||
ftc_basic_family_reset( FTC_BasicFamily family,
|
|
||||||
FTC_BasicQuery query )
|
|
||||||
{
|
|
||||||
family->attrs = query->attrs;
|
family->attrs = query->attrs;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -188,7 +180,7 @@
|
||||||
sizeof( FTC_BasicFamilyRec ),
|
sizeof( FTC_BasicFamilyRec ),
|
||||||
(FTC_MruNode_CompareFunc) ftc_basic_family_compare,
|
(FTC_MruNode_CompareFunc) ftc_basic_family_compare,
|
||||||
(FTC_MruNode_InitFunc) ftc_basic_family_init,
|
(FTC_MruNode_InitFunc) ftc_basic_family_init,
|
||||||
(FTC_MruNode_ResetFunc) ftc_basic_family_reset,
|
(FTC_MruNode_ResetFunc) NULL,
|
||||||
(FTC_MruNode_DoneFunc) NULL
|
(FTC_MruNode_DoneFunc) NULL
|
||||||
},
|
},
|
||||||
(FTC_IFamily_LoadGlyphFunc) ftc_basic_family_load_glyph
|
(FTC_IFamily_LoadGlyphFunc) ftc_basic_family_load_glyph
|
||||||
|
@ -290,7 +282,7 @@
|
||||||
sizeof( FTC_BasicFamilyRec ),
|
sizeof( FTC_BasicFamilyRec ),
|
||||||
(FTC_MruNode_CompareFunc) ftc_basic_family_compare,
|
(FTC_MruNode_CompareFunc) ftc_basic_family_compare,
|
||||||
(FTC_MruNode_InitFunc) ftc_basic_family_init,
|
(FTC_MruNode_InitFunc) ftc_basic_family_init,
|
||||||
(FTC_MruNode_ResetFunc) ftc_basic_family_reset,
|
(FTC_MruNode_ResetFunc) NULL,
|
||||||
(FTC_MruNode_DoneFunc) NULL
|
(FTC_MruNode_DoneFunc) NULL
|
||||||
},
|
},
|
||||||
(FTC_SFamily_GetCountFunc) ftc_basic_family_get_count,
|
(FTC_SFamily_GetCountFunc) ftc_basic_family_get_count,
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#define FTC_HASH_SUB_LOAD ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD )
|
#define FTC_HASH_SUB_LOAD ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD )
|
||||||
|
|
||||||
/* this one _must_ be a power of 2! */
|
/* this one _must_ be a power of 2! */
|
||||||
#define FTC_HASH_INITIAL_SIZE 8
|
#define FTC_HASH_INITIAL_SIZE 512
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
@ -45,31 +45,7 @@
|
||||||
ftc_node_mru_link( FTC_Node node,
|
ftc_node_mru_link( FTC_Node node,
|
||||||
FTC_Manager manager )
|
FTC_Manager manager )
|
||||||
{
|
{
|
||||||
FTC_Node first = manager->nodes_list;
|
FTC_MruNode_Prepend( (FTC_MruNode*)&manager->nodes_list, (FTC_MruNode)node );
|
||||||
|
|
||||||
|
|
||||||
if ( first )
|
|
||||||
{
|
|
||||||
FTC_Node last = first->mru_prev;
|
|
||||||
|
|
||||||
|
|
||||||
FT_ASSERT( last->mru_next == first );
|
|
||||||
|
|
||||||
node->mru_prev = last;
|
|
||||||
node->mru_next = first;
|
|
||||||
|
|
||||||
last->mru_next = node;
|
|
||||||
first->mru_prev = node;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FT_ASSERT( manager->num_nodes == 0 );
|
|
||||||
|
|
||||||
node->mru_next = node;
|
|
||||||
node->mru_prev = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
manager->nodes_list = node;
|
|
||||||
manager->num_nodes++;
|
manager->num_nodes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,29 +55,7 @@
|
||||||
ftc_node_mru_unlink( FTC_Node node,
|
ftc_node_mru_unlink( FTC_Node node,
|
||||||
FTC_Manager manager )
|
FTC_Manager manager )
|
||||||
{
|
{
|
||||||
FTC_Node first = manager->nodes_list;
|
FTC_MruNode_Remove( (FTC_MruNode*)&manager->nodes_list, (FTC_MruNode)node );
|
||||||
FTC_Node prev = node->mru_prev;
|
|
||||||
FTC_Node next = node->mru_next;
|
|
||||||
|
|
||||||
|
|
||||||
FT_ASSERT( first != NULL && manager->num_nodes > 0 );
|
|
||||||
FT_ASSERT( next->mru_prev == node );
|
|
||||||
FT_ASSERT( prev->mru_next == node );
|
|
||||||
|
|
||||||
next->mru_prev = prev;
|
|
||||||
prev->mru_next = next;
|
|
||||||
|
|
||||||
if ( node == first )
|
|
||||||
{
|
|
||||||
/* this is the last node in the list; update its head pointer */
|
|
||||||
if ( node == next )
|
|
||||||
manager->nodes_list = NULL;
|
|
||||||
else
|
|
||||||
manager->nodes_list = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
node->mru_next = NULL;
|
|
||||||
node->mru_prev = NULL;
|
|
||||||
manager->num_nodes--;
|
manager->num_nodes--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,27 +65,7 @@
|
||||||
ftc_node_mru_up( FTC_Node node,
|
ftc_node_mru_up( FTC_Node node,
|
||||||
FTC_Manager manager )
|
FTC_Manager manager )
|
||||||
{
|
{
|
||||||
FTC_Node first = manager->nodes_list;
|
FTC_MruNode_Up( (FTC_MruNode*)&manager->nodes_list, (FTC_MruNode)node );
|
||||||
|
|
||||||
|
|
||||||
if ( node != first )
|
|
||||||
{
|
|
||||||
FTC_Node prev = node->mru_prev;
|
|
||||||
FTC_Node next = node->mru_next;
|
|
||||||
FTC_Node last;
|
|
||||||
|
|
||||||
|
|
||||||
prev->mru_next = next;
|
|
||||||
next->mru_prev = prev;
|
|
||||||
|
|
||||||
last = first->mru_prev;
|
|
||||||
node->mru_next = first;
|
|
||||||
node->mru_prev = last;
|
|
||||||
first->mru_prev = node;
|
|
||||||
last->mru_next = node;
|
|
||||||
|
|
||||||
manager->nodes_list = node;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -142,6 +76,9 @@
|
||||||
static void
|
static void
|
||||||
ftc_cache_resize( FTC_Cache cache )
|
ftc_cache_resize( FTC_Cache cache )
|
||||||
{
|
{
|
||||||
|
#if 1
|
||||||
|
FT_UNUSED(cache);
|
||||||
|
#else
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
FTC_Node node, *pnode;
|
FTC_Node node, *pnode;
|
||||||
|
@ -236,6 +173,7 @@
|
||||||
else /* the hash table is balanced */
|
else /* the hash table is balanced */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -559,6 +497,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
AddNode:
|
AddNode:
|
||||||
|
node->ref_count = 0;
|
||||||
|
node->cache_index = (FT_UInt16) cache->index;
|
||||||
|
node->hash = hash;
|
||||||
|
|
||||||
/* don't assume that the cache has the same number of buckets, since
|
/* don't assume that the cache has the same number of buckets, since
|
||||||
* our allocation request might have triggered global cache flushing
|
* our allocation request might have triggered global cache flushing
|
||||||
*/
|
*/
|
||||||
|
@ -624,4 +566,5 @@
|
||||||
ftc_cache_resize( cache );
|
ftc_cache_resize( cache );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* END */
|
/* END */
|
||||||
|
|
|
@ -1,157 +0,0 @@
|
||||||
/***************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* ftccache.i */
|
|
||||||
/* */
|
|
||||||
/* FreeType template for generic cache. */
|
|
||||||
/* */
|
|
||||||
/* Copyright 2002 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 GEN_CACHE_FAMILY_COMPARE
|
|
||||||
#error "GEN_CACHE_FAMILY_COMPARE not defined in template instantiation"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GEN_CACHE_NODE_COMPARE
|
|
||||||
#error "GEN_CACHE_NODE_COMPARE not defined in template instantiation"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static FT_Error
|
|
||||||
GEN_CACHE_LOOKUP( FTC_Cache cache,
|
|
||||||
FTC_Query query,
|
|
||||||
FTC_Node *anode )
|
|
||||||
{
|
|
||||||
FT_LruNode lru;
|
|
||||||
FTC_Family family;
|
|
||||||
FT_UFast hash;
|
|
||||||
|
|
||||||
|
|
||||||
query->hash = 0;
|
|
||||||
query->family = NULL;
|
|
||||||
|
|
||||||
/* XXX: we break encapsulation for the sake of speed! */
|
|
||||||
{
|
|
||||||
/* first of all, find the relevant family */
|
|
||||||
FT_LruList list = cache->families;
|
|
||||||
FT_LruNode fam, *pfam;
|
|
||||||
|
|
||||||
|
|
||||||
pfam = &list->nodes;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
fam = *pfam;
|
|
||||||
if ( fam == NULL )
|
|
||||||
goto Normal;
|
|
||||||
|
|
||||||
if ( GEN_CACHE_FAMILY_COMPARE( fam, query, list->data ) )
|
|
||||||
break;
|
|
||||||
|
|
||||||
pfam = &fam->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
FT_ASSERT( fam != NULL );
|
|
||||||
|
|
||||||
/* move to top of list when needed */
|
|
||||||
if ( fam != list->nodes )
|
|
||||||
{
|
|
||||||
*pfam = fam->next;
|
|
||||||
fam->next = list->nodes;
|
|
||||||
list->nodes = fam;
|
|
||||||
}
|
|
||||||
|
|
||||||
lru = fam;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
FTC_Node node, *pnode, *bucket;
|
|
||||||
|
|
||||||
|
|
||||||
family = (FTC_Family)lru;
|
|
||||||
hash = query->hash;
|
|
||||||
|
|
||||||
{
|
|
||||||
FT_UInt idx;
|
|
||||||
|
|
||||||
|
|
||||||
idx = hash & cache->mask;
|
|
||||||
if ( idx < cache->p )
|
|
||||||
idx = hash & ( cache->mask * 2 + 1 );
|
|
||||||
|
|
||||||
bucket = cache->buckets + idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
pnode = bucket;
|
|
||||||
|
|
||||||
for ( ;; )
|
|
||||||
{
|
|
||||||
node = *pnode;
|
|
||||||
if ( node == NULL )
|
|
||||||
goto Normal;
|
|
||||||
|
|
||||||
if ( node->hash == hash &&
|
|
||||||
(FT_UInt)node->fam_index == family->fam_index &&
|
|
||||||
GEN_CACHE_NODE_COMPARE( node, query, cache ) )
|
|
||||||
{
|
|
||||||
/* we place the following out of the loop to make it */
|
|
||||||
/* as small as possible... */
|
|
||||||
goto Found;
|
|
||||||
}
|
|
||||||
|
|
||||||
pnode = &node->link;
|
|
||||||
}
|
|
||||||
|
|
||||||
Normal:
|
|
||||||
return ftc_cache_lookup( cache, query, anode );
|
|
||||||
|
|
||||||
Found:
|
|
||||||
/* move to head of bucket list */
|
|
||||||
if ( pnode != bucket )
|
|
||||||
{
|
|
||||||
*pnode = node->link;
|
|
||||||
node->link = *bucket;
|
|
||||||
*bucket = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* move to head of MRU list */
|
|
||||||
if ( node != cache->manager->nodes_list )
|
|
||||||
{
|
|
||||||
/* XXX: again, this is an inlined version of ftc_node_mru_up */
|
|
||||||
FTC_Manager manager = cache->manager;
|
|
||||||
FTC_Node first = manager->nodes_list;
|
|
||||||
FTC_Node prev = node->mru_prev;
|
|
||||||
FTC_Node next = node->mru_next;
|
|
||||||
FTC_Node last;
|
|
||||||
|
|
||||||
|
|
||||||
prev->mru_next = next;
|
|
||||||
next->mru_prev = prev;
|
|
||||||
|
|
||||||
last = first->mru_prev;
|
|
||||||
node->mru_next = first;
|
|
||||||
node->mru_prev = last;
|
|
||||||
first->mru_prev = node;
|
|
||||||
last->mru_next = node;
|
|
||||||
|
|
||||||
manager->nodes_list = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
*anode = node;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef GEN_CACHE_NODE_COMPARE
|
|
||||||
#undef GEN_CACHE_FAMILY_COMPARE
|
|
||||||
#undef GEN_CACHE_LOOKUP
|
|
||||||
|
|
||||||
|
|
||||||
/* END */
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "ftcerror.h"
|
#include "ftcerror.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* create a new chunk node, setting its cache index and ref count */
|
/* create a new chunk node, setting its cache index and ref count */
|
||||||
FT_EXPORT_DEF( void )
|
FT_EXPORT_DEF( void )
|
||||||
FTC_GNode_Init( FTC_GNode gnode,
|
FTC_GNode_Init( FTC_GNode gnode,
|
||||||
|
@ -34,6 +35,7 @@
|
||||||
{
|
{
|
||||||
gnode->family = family;
|
gnode->family = family;
|
||||||
gnode->gindex = gindex;
|
gnode->gindex = gindex;
|
||||||
|
|
||||||
family->num_nodes++;
|
family->num_nodes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,13 +81,14 @@
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
FT_EXPORT_DEF( void )
|
FT_EXPORT_DEF( void )
|
||||||
ftc_family_init( FTC_Family family,
|
FTC_Family_Init( FTC_Family family,
|
||||||
FTC_Cache cache )
|
FTC_Cache cache )
|
||||||
{
|
{
|
||||||
FTC_GCacheClass clazz = FTC_CACHE__GCACHE_CLASS(cache);
|
FTC_GCacheClass clazz = FTC_CACHE__GCACHE_CLASS(cache);
|
||||||
|
|
||||||
family->clazz = clazz->family_class;
|
family->clazz = clazz->family_class;
|
||||||
family->num_nodes = 0;
|
family->num_nodes = 0;
|
||||||
|
family->cache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,14 +138,26 @@
|
||||||
FTC_Node *anode )
|
FTC_Node *anode )
|
||||||
{
|
{
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
|
FTC_Family family;
|
||||||
|
|
||||||
query->gindex = gindex;
|
query->gindex = gindex;
|
||||||
|
|
||||||
error = FTC_MruList_Lookup( &cache->families, query,
|
family = (FTC_Family) FTC_MruList_Lookup( &cache->families, query );
|
||||||
(FTC_MruNode*) &query->family );
|
if ( family == NULL )
|
||||||
if ( !error )
|
{
|
||||||
|
error = FTC_MruList_New( &cache->families, query, (FTC_MruNode*) &family );
|
||||||
|
if ( error )
|
||||||
|
{
|
||||||
|
*anode = NULL;
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query->family = family;
|
||||||
|
|
||||||
error = FTC_Cache_Lookup( FTC_CACHE(cache), hash, query, anode );
|
error = FTC_Cache_Lookup( FTC_CACHE(cache), hash, query, anode );
|
||||||
|
|
||||||
|
Exit:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,7 @@
|
||||||
FTC_Scaler scaler,
|
FTC_Scaler scaler,
|
||||||
FT_Size *asize )
|
FT_Size *asize )
|
||||||
{
|
{
|
||||||
FT_Error error;
|
FT_Error error = 0;
|
||||||
FTC_SizeNode node;
|
FTC_SizeNode node;
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,16 +156,20 @@
|
||||||
if ( !manager )
|
if ( !manager )
|
||||||
return FTC_Err_Invalid_Cache_Handle;
|
return FTC_Err_Invalid_Cache_Handle;
|
||||||
|
|
||||||
error = FTC_MruList_Lookup( &manager->sizes,
|
error = FTC_MruList_Get( &manager->sizes, scaler, (FTC_MruNode*) &node );
|
||||||
scaler,
|
|
||||||
(FTC_MruNode*) &node );
|
|
||||||
if ( !error )
|
if ( !error )
|
||||||
|
{
|
||||||
*asize = node->size;
|
*asize = node->size;
|
||||||
|
FT_Activate_Size( node->size );
|
||||||
|
}
|
||||||
|
|
||||||
|
Exit:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/***** *****/
|
/***** *****/
|
||||||
|
@ -211,9 +215,6 @@
|
||||||
ftc_face_node_done( FTC_FaceNode node,
|
ftc_face_node_done( FTC_FaceNode node,
|
||||||
FTC_Manager manager )
|
FTC_Manager manager )
|
||||||
{
|
{
|
||||||
FT_Memory memory = manager->memory;
|
|
||||||
|
|
||||||
|
|
||||||
/* we must begin by removing all scalers for the target face */
|
/* we must begin by removing all scalers for the target face */
|
||||||
/* from the manager's list */
|
/* from the manager's list */
|
||||||
FTC_MruList_RemoveSelection(
|
FTC_MruList_RemoveSelection(
|
||||||
|
@ -222,11 +223,12 @@
|
||||||
node->face_id );
|
node->face_id );
|
||||||
|
|
||||||
/* all right, we can discard the face now */
|
/* all right, we can discard the face now */
|
||||||
|
if ( node->face )
|
||||||
|
{
|
||||||
FT_Done_Face( node->face );
|
FT_Done_Face( node->face );
|
||||||
node->face = NULL;
|
node->face = NULL;
|
||||||
|
}
|
||||||
node->face_id = NULL;
|
node->face_id = NULL;
|
||||||
|
|
||||||
FT_FREE( node );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -257,7 +259,7 @@
|
||||||
FTC_FaceID face_id,
|
FTC_FaceID face_id,
|
||||||
FT_Face *aface )
|
FT_Face *aface )
|
||||||
{
|
{
|
||||||
FT_Error error;
|
FT_Error error = 0;
|
||||||
FTC_FaceNode node;
|
FTC_FaceNode node;
|
||||||
|
|
||||||
|
|
||||||
|
@ -269,12 +271,17 @@
|
||||||
if ( !manager )
|
if ( !manager )
|
||||||
return FTC_Err_Invalid_Cache_Handle;
|
return FTC_Err_Invalid_Cache_Handle;
|
||||||
|
|
||||||
error = FTC_MruList_Lookup( &manager->faces,
|
node = (FTC_FaceNode) FTC_MruList_Lookup( &manager->faces, face_id );
|
||||||
face_id,
|
if ( node == NULL )
|
||||||
(FTC_MruNode*) &node );
|
{
|
||||||
if ( !error )
|
error = FTC_MruList_New( &manager->faces, face_id, (FTC_MruNode*) &node );
|
||||||
|
if (error)
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
*aface = node->face;
|
*aface = node->face;
|
||||||
|
|
||||||
|
Exit:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,7 +429,7 @@
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
FTC_Cache cache = manager->caches + node->cache_index;
|
FTC_Cache cache = manager->caches[node->cache_index];
|
||||||
|
|
||||||
if ( (FT_UInt)node->cache_index >= manager->num_caches )
|
if ( (FT_UInt)node->cache_index >= manager->num_caches )
|
||||||
FT_ERROR(( "FTC_Manager_Check: invalid node (cache index = %ld\n",
|
FT_ERROR(( "FTC_Manager_Check: invalid node (cache index = %ld\n",
|
||||||
|
@ -432,7 +439,7 @@
|
||||||
weight += cache->clazz.node_weight( node, cache );
|
weight += cache->clazz.node_weight( node, cache );
|
||||||
}
|
}
|
||||||
|
|
||||||
node = node->mru_next;
|
node = FTC_NODE__MRU_NEXT(node);
|
||||||
|
|
||||||
} while ( node != first );
|
} while ( node != first );
|
||||||
|
|
||||||
|
@ -451,7 +458,7 @@
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
node = node->mru_next;
|
node = FTC_NODE__MRU_NEXT(node);
|
||||||
|
|
||||||
} while ( node != first );
|
} while ( node != first );
|
||||||
|
|
||||||
|
@ -494,20 +501,23 @@
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* go to last node - it's a circular list */
|
/* go to last node - it's a circular list */
|
||||||
node = first->mru_prev;
|
node = FTC_NODE__MRU_PREV(first);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
FTC_Node prev = node->mru_prev;
|
FTC_Node prev = FTC_NODE__MRU_PREV(node);
|
||||||
|
|
||||||
|
|
||||||
prev = ( node == first ) ? NULL : node->mru_prev;
|
prev = FTC_NODE__MRU_PREV(node);
|
||||||
|
|
||||||
if ( node->ref_count <= 0 )
|
if ( node->ref_count <= 0 )
|
||||||
ftc_node_destroy( node, manager );
|
ftc_node_destroy( node, manager );
|
||||||
|
|
||||||
|
if ( node == first )
|
||||||
|
break;
|
||||||
|
|
||||||
node = prev;
|
node = prev;
|
||||||
|
|
||||||
} while ( node && manager->cur_weight > manager->max_weight );
|
} while ( manager->cur_weight > manager->max_weight );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -576,11 +586,10 @@
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* go to last node - it's a circular list */
|
/* go to last node - it's a circular list */
|
||||||
node = first->mru_prev;
|
node = FTC_NODE__MRU_PREV( first );
|
||||||
for ( result = 0; result < count; )
|
for ( result = 0; result < count; )
|
||||||
{
|
{
|
||||||
FTC_Node prev = node->mru_prev;
|
FTC_Node prev = FTC_NODE__MRU_PREV(node);
|
||||||
|
|
||||||
|
|
||||||
/* don't touch locked nodes */
|
/* don't touch locked nodes */
|
||||||
if ( node->ref_count <= 0 )
|
if ( node->ref_count <= 0 )
|
||||||
|
@ -589,7 +598,7 @@
|
||||||
result++;
|
result++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( prev == manager->nodes_list )
|
if ( node == first )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
node = prev;
|
node = prev;
|
||||||
|
|
|
@ -6,6 +6,94 @@
|
||||||
|
|
||||||
#include "ftcerror.h"
|
#include "ftcerror.h"
|
||||||
|
|
||||||
|
|
||||||
|
FT_EXPORT_DEF( void )
|
||||||
|
FTC_MruNode_Prepend( FTC_MruNode *plist,
|
||||||
|
FTC_MruNode node )
|
||||||
|
{
|
||||||
|
FTC_MruNode first = *plist;
|
||||||
|
|
||||||
|
if ( first )
|
||||||
|
{
|
||||||
|
FTC_MruNode last = first->prev;
|
||||||
|
|
||||||
|
last->next = node;
|
||||||
|
first->prev = node;
|
||||||
|
node->prev = last;
|
||||||
|
node->next = first;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node->next = node;
|
||||||
|
node->prev = node;
|
||||||
|
}
|
||||||
|
*plist = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FT_EXPORT_DEF( void )
|
||||||
|
FTC_MruNode_Up( FTC_MruNode *plist,
|
||||||
|
FTC_MruNode node )
|
||||||
|
{
|
||||||
|
FTC_MruNode first = *plist;
|
||||||
|
|
||||||
|
FT_ASSERT( first != NULL );
|
||||||
|
|
||||||
|
if ( node != first )
|
||||||
|
{
|
||||||
|
FTC_MruNode prev = node->prev;
|
||||||
|
FTC_MruNode next = node->next;
|
||||||
|
FTC_MruNode last;
|
||||||
|
|
||||||
|
prev->next = next;
|
||||||
|
next->prev = prev;
|
||||||
|
|
||||||
|
last = first->prev;
|
||||||
|
|
||||||
|
first->prev = node;
|
||||||
|
last->next = node;
|
||||||
|
|
||||||
|
node->prev = last;
|
||||||
|
node->next = first;
|
||||||
|
|
||||||
|
*plist = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FT_EXPORT( void )
|
||||||
|
FTC_MruNode_Remove( FTC_MruNode *plist,
|
||||||
|
FTC_MruNode node )
|
||||||
|
{
|
||||||
|
FTC_MruNode first = *plist;
|
||||||
|
FTC_MruNode prev, next;
|
||||||
|
|
||||||
|
FT_ASSERT( first != NULL );
|
||||||
|
|
||||||
|
next = node->next;
|
||||||
|
prev = node->prev;
|
||||||
|
|
||||||
|
if ( node == next )
|
||||||
|
{
|
||||||
|
FT_ASSERT( node == prev );
|
||||||
|
FT_ASSERT( node == first );
|
||||||
|
|
||||||
|
*plist = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prev->next = next;
|
||||||
|
next->prev = prev;
|
||||||
|
|
||||||
|
if ( node == first )
|
||||||
|
*plist = next;
|
||||||
|
}
|
||||||
|
node->prev = NULL;
|
||||||
|
node->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FT_EXPORT_DEF( void )
|
FT_EXPORT_DEF( void )
|
||||||
FTC_MruList_Init( FTC_MruList list,
|
FTC_MruList_Init( FTC_MruList list,
|
||||||
FTC_MruListClass clazz,
|
FTC_MruListClass clazz,
|
||||||
|
@ -22,30 +110,33 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
ftc_mrulist_free_nodes( FTC_MruList list,
|
|
||||||
FTC_MruNode *plist )
|
|
||||||
{
|
|
||||||
FT_Memory memory = list->memory;
|
|
||||||
|
|
||||||
while ( *plist )
|
|
||||||
{
|
|
||||||
FTC_MruNode node = *plist;
|
|
||||||
|
|
||||||
*plist = node->next;
|
|
||||||
|
|
||||||
if ( list->clazz.node_done )
|
|
||||||
list->clazz.node_done( node, list->data );
|
|
||||||
|
|
||||||
FT_FREE( node );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FT_EXPORT( void )
|
FT_EXPORT( void )
|
||||||
FTC_MruList_Reset( FTC_MruList list )
|
FTC_MruList_Reset( FTC_MruList list )
|
||||||
{
|
{
|
||||||
ftc_mrulist_free_nodes( list, &list->nodes );
|
FT_Memory memory = list->memory;
|
||||||
|
FTC_MruNode first = list->nodes;
|
||||||
|
|
||||||
|
if ( first )
|
||||||
|
{
|
||||||
|
FTC_MruNode node = first;
|
||||||
|
FTC_MruNode next;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
next = node->next;
|
||||||
|
|
||||||
|
if ( list->clazz.node_done )
|
||||||
|
list->clazz.node_done( node, list->data );
|
||||||
|
|
||||||
|
FT_FREE( node );
|
||||||
|
|
||||||
|
node = next;
|
||||||
|
}
|
||||||
|
while ( node != first );
|
||||||
|
}
|
||||||
|
list->nodes = NULL;
|
||||||
list->num_nodes = 0;
|
list->num_nodes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,75 +148,91 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FT_EXPORT( FT_Error )
|
FT_EXPORT_DEF( void )
|
||||||
|
FTC_MruList_Up( FTC_MruList list,
|
||||||
|
FTC_MruNode node )
|
||||||
|
{
|
||||||
|
FTC_MruNode_Up( &list->nodes, node );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FT_EXPORT_DEF( FTC_MruNode )
|
||||||
FTC_MruList_Lookup( FTC_MruList list,
|
FTC_MruList_Lookup( FTC_MruList list,
|
||||||
|
FT_Pointer key )
|
||||||
|
{
|
||||||
|
FTC_MruNode_CompareFunc compare = list->clazz.node_compare;
|
||||||
|
FTC_MruNode node, first;
|
||||||
|
|
||||||
|
first = list->nodes;
|
||||||
|
node = NULL;
|
||||||
|
|
||||||
|
if ( first )
|
||||||
|
{
|
||||||
|
node = first;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ( compare( node, key ) )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
|
node = node->next;
|
||||||
|
|
||||||
|
} while ( node != first );
|
||||||
|
|
||||||
|
node = NULL;
|
||||||
|
}
|
||||||
|
Exit:
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FT_EXPORT_DEF( FT_Error )
|
||||||
|
FTC_MruList_New( FTC_MruList list,
|
||||||
FT_Pointer key,
|
FT_Pointer key,
|
||||||
FTC_MruNode *anode )
|
FTC_MruNode *anode )
|
||||||
{
|
{
|
||||||
FT_Memory memory = list->memory;
|
FT_Memory memory = list->memory;
|
||||||
FTC_MruNode_CompareFunc compare = list->clazz.node_compare;
|
FT_Error error;
|
||||||
FTC_MruNode *plast, *pnode, *pfirst;
|
|
||||||
FTC_MruNode node;
|
FTC_MruNode node;
|
||||||
FT_Error error = 0;
|
|
||||||
|
|
||||||
pfirst = &list->nodes;
|
|
||||||
plast = pnode = pfirst;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
node = *pnode;
|
|
||||||
if ( node == NULL )
|
|
||||||
goto NewNode;
|
|
||||||
if ( compare( node, key ) )
|
|
||||||
break;
|
|
||||||
plast = pnode;
|
|
||||||
pnode = &node->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( node != *pfirst )
|
|
||||||
{
|
|
||||||
*pnode = node->next;
|
|
||||||
node->next = *pfirst;
|
|
||||||
*pfirst = node;
|
|
||||||
}
|
|
||||||
goto Exit;
|
|
||||||
|
|
||||||
NewNode:
|
|
||||||
if ( list->max_nodes > 0 && list->num_nodes >= list->max_nodes )
|
if ( list->max_nodes > 0 && list->num_nodes >= list->max_nodes )
|
||||||
{
|
{
|
||||||
node = *plast;
|
FT_ASSERT( list->nodes != NULL );
|
||||||
|
|
||||||
if ( node )
|
node = list->nodes->prev; /* last node */
|
||||||
{
|
|
||||||
*plast = NULL;
|
|
||||||
list->num_nodes--;
|
|
||||||
|
|
||||||
if ( list->clazz.node_reset )
|
if ( list->clazz.node_reset )
|
||||||
{
|
{
|
||||||
|
FTC_MruNode_Up( &list->nodes, node );
|
||||||
|
|
||||||
error = list->clazz.node_reset( node, key, list->data );
|
error = list->clazz.node_reset( node, key, list->data );
|
||||||
if ( !error ) goto AddNode;
|
if ( !error )
|
||||||
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FTC_MruNode_Remove( &list->nodes, node );
|
||||||
|
list->num_nodes--;
|
||||||
|
|
||||||
|
if ( list->clazz.node_done )
|
||||||
list->clazz.node_done( node, list->data );
|
list->clazz.node_done( node, list->data );
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else if ( FT_ALLOC( node, list->clazz.node_size ) )
|
|
||||||
goto Exit;
|
|
||||||
|
|
||||||
error = list->clazz.node_init( node, key, list->data );
|
|
||||||
if ( error )
|
|
||||||
{
|
{
|
||||||
|
if ( FT_ALLOC( node, list->clazz.node_size ) )
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
error = list->clazz.node_init( node, key, list->data );
|
||||||
|
if ( !error )
|
||||||
|
{
|
||||||
|
FTC_MruNode_Prepend( &list->nodes, node );
|
||||||
|
list->num_nodes++;
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
if ( list->clazz.node_done )
|
if ( list->clazz.node_done )
|
||||||
list->clazz.node_done( node, list->data );
|
list->clazz.node_done( node, list->data );
|
||||||
|
|
||||||
FT_FREE( node );
|
FT_FREE( node );
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddNode:
|
|
||||||
node->next = list->nodes;
|
|
||||||
list->nodes = node;
|
|
||||||
list->num_nodes++;
|
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
*anode = node;
|
*anode = node;
|
||||||
|
@ -133,40 +240,43 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FT_EXPORT_DEF( FT_Error )
|
||||||
|
FTC_MruList_Get( FTC_MruList list,
|
||||||
|
FT_Pointer key,
|
||||||
|
FTC_MruNode *anode )
|
||||||
|
{
|
||||||
|
FT_Error error = 0;
|
||||||
|
FTC_MruNode node;
|
||||||
|
|
||||||
|
node = FTC_MruList_Lookup( list, key );
|
||||||
|
if ( node == NULL )
|
||||||
|
{
|
||||||
|
error = FTC_MruList_New( list, key, &node );
|
||||||
|
if ( error )
|
||||||
|
node = NULL;
|
||||||
|
}
|
||||||
|
*anode = node;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FT_EXPORT_DEF( void )
|
FT_EXPORT_DEF( void )
|
||||||
FTC_MruList_Remove( FTC_MruList list,
|
FTC_MruList_Remove( FTC_MruList list,
|
||||||
FTC_MruNode node )
|
FTC_MruNode node )
|
||||||
{
|
|
||||||
FTC_MruNode *pnode = &list->nodes;
|
|
||||||
|
|
||||||
for ( ;; )
|
|
||||||
{
|
|
||||||
if ( *pnode == NULL ) /* should not happen !! */
|
|
||||||
{
|
|
||||||
FT_ERROR(( "%s: trying to remove unknown node !!\n",
|
|
||||||
"FTC_MruList_Remove" ));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( *pnode == node )
|
|
||||||
break;
|
|
||||||
|
|
||||||
pnode = &node->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pnode = node->next;
|
|
||||||
node->next = NULL;
|
|
||||||
list->num_nodes--;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
FT_Memory memory = list->memory;
|
FT_Memory memory = list->memory;
|
||||||
|
|
||||||
|
FT_ASSERT( list->nodes != NULL && list->num_nodes > 0 );
|
||||||
|
|
||||||
|
FTC_MruNode_Remove( &list->nodes, node );
|
||||||
|
list->num_nodes--;
|
||||||
|
|
||||||
if ( list->clazz.node_done )
|
if ( list->clazz.node_done )
|
||||||
list->clazz.node_done( node, list->data );
|
list->clazz.node_done( node, list->data );
|
||||||
|
|
||||||
FT_FREE( node );
|
FT_FREE( node );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FT_EXPORT_DEF( void )
|
FT_EXPORT_DEF( void )
|
||||||
|
@ -174,30 +284,29 @@
|
||||||
FTC_MruNode_CompareFunc select,
|
FTC_MruNode_CompareFunc select,
|
||||||
FT_Pointer key )
|
FT_Pointer key )
|
||||||
{
|
{
|
||||||
FTC_MruNode *pnode = &list->nodes;
|
FTC_MruNode first = list->nodes;
|
||||||
FTC_MruNode node, free = NULL;;
|
|
||||||
|
|
||||||
if ( select )
|
while ( first && select( first, key ) )
|
||||||
{
|
{
|
||||||
for (;;)
|
FTC_MruList_Remove( list, first );
|
||||||
{
|
first = list->nodes;
|
||||||
FTC_MruNode node = *pnode;
|
}
|
||||||
|
|
||||||
if ( node == NULL )
|
if ( first )
|
||||||
break;
|
{
|
||||||
|
FTC_MruNode node = first->next;
|
||||||
|
FTC_MruNode next;
|
||||||
|
|
||||||
|
while ( node != first )
|
||||||
|
{
|
||||||
|
next = node->next;
|
||||||
|
|
||||||
if ( select( node, key ) )
|
if ( select( node, key ) )
|
||||||
{
|
FTC_MruList_Remove( list, node );
|
||||||
*pnode = node->next;
|
|
||||||
node->next = free;
|
|
||||||
free = node;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
pnode = &node->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ftc_mrulist_free_nodes( list, &free );
|
node = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* END */
|
/* END */
|
||||||
|
|
|
@ -91,7 +91,7 @@
|
||||||
FTC_SFamilyClass clazz;
|
FTC_SFamilyClass clazz;
|
||||||
|
|
||||||
|
|
||||||
if ( (FT_UInt)gindex >= gnode->gindex + snode->count )
|
if ( (FT_UInt)(gindex - gnode->gindex) >= snode->count )
|
||||||
{
|
{
|
||||||
FT_ERROR(( "ftc_snode_load: invalid glyph index" ));
|
FT_ERROR(( "ftc_snode_load: invalid glyph index" ));
|
||||||
return FTC_Err_Invalid_Argument;
|
return FTC_Err_Invalid_Argument;
|
||||||
|
@ -267,7 +267,8 @@
|
||||||
FT_UInt gindex = gquery->gindex;
|
FT_UInt gindex = gquery->gindex;
|
||||||
FT_Bool result;
|
FT_Bool result;
|
||||||
|
|
||||||
result = FT_BOOL( (FT_UInt)(gindex - gnode->gindex) < snode->count );
|
result = FT_BOOL( gnode->family == gquery->family &&
|
||||||
|
(FT_UInt)(gindex - gnode->gindex) < snode->count );
|
||||||
if ( result )
|
if ( result )
|
||||||
{
|
{
|
||||||
/* check if we need to load the glyph bitmap now */
|
/* check if we need to load the glyph bitmap now */
|
||||||
|
|
Loading…
Reference in New Issue