📄 ftcmanag.c
字号:
if ( max_sizes == 0 )
max_sizes = FTC_MAX_SIZES_DEFAULT;
if ( max_bytes == 0 )
max_bytes = FTC_MAX_BYTES_DEFAULT;
manager->library = library;
manager->memory = memory;
manager->max_weight = max_bytes;
manager->request_face = requester;
manager->request_data = req_data;
FTC_MruList_Init( &manager->faces,
&ftc_face_list_class,
max_faces,
manager,
memory );
FTC_MruList_Init( &manager->sizes,
&ftc_size_list_class,
max_sizes,
manager,
memory );
*amanager = manager;
Exit:
return error;
}
/* documentation is in ftcache.h */
FT_EXPORT_DEF( void )
FTC_Manager_Done( FTC_Manager manager )
{
FT_Memory memory;
FT_UInt idx;
if ( !manager || !manager->library )
return;
memory = manager->memory;
/* now discard all caches */
for (idx = manager->num_caches; idx-- > 0; )
{
FTC_Cache cache = manager->caches[idx];
if ( cache )
{
cache->clazz.cache_done( cache );
FT_FREE( cache );
manager->caches[idx] = NULL;
}
}
manager->num_caches = 0;
/* discard faces and sizes */
FTC_MruList_Done( &manager->sizes );
FTC_MruList_Done( &manager->faces );
manager->library = NULL;
manager->memory = NULL;
FT_FREE( manager );
}
/* documentation is in ftcache.h */
FT_EXPORT_DEF( void )
FTC_Manager_Reset( FTC_Manager manager )
{
if ( manager )
{
FTC_MruList_Reset( &manager->sizes );
FTC_MruList_Reset( &manager->faces );
}
/* XXX: FIXME: flush the caches? */
}
#ifdef FT_DEBUG_ERROR
static void
FTC_Manager_Check( FTC_Manager manager )
{
FTC_Node node, first;
first = manager->nodes_list;
/* check node weights */
if ( first )
{
FT_ULong weight = 0;
node = first;
do
{
FTC_Cache cache = manager->caches[node->cache_index];
if ( (FT_UInt)node->cache_index >= manager->num_caches )
FT_ERROR(( "FTC_Manager_Check: invalid node (cache index = %ld\n",
node->cache_index ));
else
weight += cache->clazz.node_weight( node, cache );
node = FTC_NODE__NEXT( node );
} while ( node != first );
if ( weight != manager->cur_weight )
FT_ERROR(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n",
manager->cur_weight, weight ));
}
/* check circular list */
if ( first )
{
FT_UFast count = 0;
node = first;
do
{
count++;
node = FTC_NODE__NEXT( node );
} while ( node != first );
if ( count != manager->num_nodes )
FT_ERROR((
"FTC_Manager_Check: invalid cache node count %d instead of %d\n",
manager->num_nodes, count ));
}
}
#endif /* FT_DEBUG_ERROR */
/* `Compress' the manager's data, i.e., get rid of old cache nodes */
/* that are not referenced anymore in order to limit the total */
/* memory used by the cache. */
/* documentation is in ftcmanag.h */
FT_LOCAL_DEF( void )
FTC_Manager_Compress( FTC_Manager manager )
{
FTC_Node node, first;
if ( !manager )
return;
first = manager->nodes_list;
#ifdef FT_DEBUG_ERROR
FTC_Manager_Check( manager );
FT_ERROR(( "compressing, weight = %ld, max = %ld, nodes = %d\n",
manager->cur_weight, manager->max_weight,
manager->num_nodes ));
#endif
if ( manager->cur_weight < manager->max_weight || first == NULL )
return;
/* go to last node -- it's a circular list */
node = FTC_NODE__PREV( first );
do
{
FTC_Node prev;
prev = ( node == first ) ? NULL : FTC_NODE__PREV( node );
if ( node->ref_count <= 0 )
ftc_node_destroy( node, manager );
node = prev;
} while ( node && manager->cur_weight > manager->max_weight );
}
/* documentation is in ftcmanag.h */
FT_LOCAL_DEF( FT_Error )
FTC_Manager_RegisterCache( FTC_Manager manager,
FTC_CacheClass clazz,
FTC_Cache *acache )
{
FT_Error error = FTC_Err_Invalid_Argument;
FTC_Cache cache = NULL;
if ( manager && clazz && acache )
{
FT_Memory memory = manager->memory;
if ( manager->num_caches >= FTC_MAX_CACHES )
{
error = FTC_Err_Too_Many_Caches;
FT_ERROR(( "%s: too many registered caches\n",
"FTC_Manager_Register_Cache" ));
goto Exit;
}
if ( !FT_ALLOC( cache, clazz->cache_size ) )
{
cache->manager = manager;
cache->memory = memory;
cache->clazz = clazz[0];
cache->org_class = clazz;
/* THIS IS VERY IMPORTANT! IT WILL WRETCH THE MANAGER */
/* IF IT IS NOT SET CORRECTLY */
cache->index = manager->num_caches;
error = clazz->cache_init( cache );
if ( error )
{
clazz->cache_done( cache );
FT_FREE( cache );
goto Exit;
}
manager->caches[manager->num_caches++] = cache;
}
}
Exit:
*acache = cache;
return error;
}
FT_LOCAL_DEF( FT_UInt )
FTC_Manager_FlushN( FTC_Manager manager,
FT_UInt count )
{
FTC_Node first = manager->nodes_list;
FTC_Node node;
FT_UInt result;
/* try to remove `count' nodes from the list */
if ( first == NULL ) /* empty list! */
return 0;
/* go to last node - it's a circular list */
node = FTC_NODE__PREV(first);
for ( result = 0; result < count; )
{
FTC_Node prev = FTC_NODE__PREV( node );
/* don't touch locked nodes */
if ( node->ref_count <= 0 )
{
ftc_node_destroy( node, manager );
result++;
}
if ( node == first )
break;
node = prev;
}
return result;
}
/* documentation is in ftcache.h */
FT_EXPORT_DEF( void )
FTC_Manager_RemoveFaceID( FTC_Manager manager,
FTC_FaceID face_id )
{
FT_UInt nn;
/* this will remove all FTC_SizeNode that correspond to
* the face_id as well
*/
FTC_MruList_RemoveSelection( &manager->faces, NULL, face_id );
for ( nn = 0; nn < manager->num_caches; nn++ )
FTC_Cache_RemoveFaceID( manager->caches[nn], face_id );
}
/* documentation is in ftcache.h */
FT_EXPORT_DEF( void )
FTC_Node_Unref( FTC_Node node,
FTC_Manager manager )
{
if ( node && (FT_UInt)node->cache_index < manager->num_caches )
node->ref_count--;
}
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
FT_EXPORT_DEF( FT_Error )
FTC_Manager_Lookup_Face( FTC_Manager manager,
FTC_FaceID face_id,
FT_Face *aface )
{
return FTC_Manager_LookupFace( manager, face_id, aface );
}
FT_EXPORT( FT_Error )
FTC_Manager_Lookup_Size( FTC_Manager manager,
FTC_Font font,
FT_Face *aface,
FT_Size *asize )
{
FTC_ScalerRec scaler;
FT_Error error;
FT_Size size;
FT_Face face;
scaler.face_id = font->face_id;
scaler.width = font->pix_width;
scaler.height = font->pix_height;
scaler.pixel = TRUE;
scaler.x_res = 0;
scaler.y_res = 0;
error = FTC_Manager_LookupSize( manager, &scaler, &size );
if ( error )
{
face = NULL;
size = NULL;
}
else
face = size->face;
if ( aface )
*aface = face;
if ( asize )
*asize = size;
return error;
}
#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
/* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -