2000-09-19 03:11:11 +02:00
|
|
|
/***************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* ftcglyph.c */
|
|
|
|
/* */
|
2000-10-12 07:05:40 +02:00
|
|
|
/* FreeType Glyph Image (FT_Glyph) cache (body). */
|
2000-09-19 03:11:11 +02:00
|
|
|
/* */
|
|
|
|
/* Copyright 2000 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. */
|
|
|
|
/* */
|
|
|
|
/***************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
#include <freetype/cache/ftcglyph.h>
|
|
|
|
#include <freetype/fterrors.h>
|
|
|
|
#include <freetype/internal/ftobjs.h>
|
|
|
|
#include <freetype/internal/ftlist.h>
|
2000-10-31 23:13:54 +01:00
|
|
|
#include <freetype/internal/ftdebug.h>
|
2000-09-19 03:11:11 +02:00
|
|
|
|
2000-10-12 07:05:40 +02:00
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/***** *****/
|
|
|
|
/***** GLYPH NODES *****/
|
|
|
|
/***** *****/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
/* create a new glyph node, setting its cache index and ref count */
|
2000-11-04 02:55:49 +01:00
|
|
|
FT_EXPORT_DEF( void ) FTC_GlyphNode_Init( FTC_GlyphNode node,
|
|
|
|
FTC_GlyphSet gset,
|
|
|
|
FT_UInt gindex )
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
2000-10-28 15:17:11 +02:00
|
|
|
FTC_Glyph_Cache cache = gset->cache;
|
2000-09-19 03:11:11 +02:00
|
|
|
FTC_CacheNode_Data* data = FTC_CACHENODE_TO_DATA_P( &node->root );
|
|
|
|
|
|
|
|
|
2000-10-12 07:05:40 +02:00
|
|
|
data->cache_index = (FT_UShort)cache->root.cache_index;
|
|
|
|
data->ref_count = (FT_Short) 0;
|
2000-10-28 15:17:11 +02:00
|
|
|
node->gset_index = (FT_UShort)gset->gset_index;
|
2000-10-12 07:05:40 +02:00
|
|
|
node->glyph_index = (FT_UShort)gindex;
|
|
|
|
}
|
|
|
|
|
2000-09-19 03:11:11 +02:00
|
|
|
|
2000-10-12 07:05:40 +02:00
|
|
|
/* Important: This function is called from the cache manager to */
|
|
|
|
/* destroy a given cache node during `cache compression'. The */
|
2000-10-29 01:34:45 +02:00
|
|
|
/* second argument is always `cache.cache_data'. Thus be */
|
2000-10-28 09:26:59 +02:00
|
|
|
/* certain that the function FTC_Glyph_Cache_New() does indeed */
|
2000-10-29 01:34:45 +02:00
|
|
|
/* set its `cache_data' field correctly, otherwise bad things */
|
2000-10-12 07:05:40 +02:00
|
|
|
/* will happen! */
|
2000-09-19 03:11:11 +02:00
|
|
|
|
2000-11-04 02:55:49 +01:00
|
|
|
FT_EXPORT_DEF( void ) FTC_GlyphNode_Destroy( FTC_GlyphNode node,
|
|
|
|
FTC_Glyph_Cache cache )
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
2000-10-28 15:17:11 +02:00
|
|
|
FT_LruNode gset_lru = cache->gsets_lru->nodes + node->gset_index;
|
|
|
|
FTC_GlyphSet gset = (FTC_GlyphSet)gset_lru->root.data;
|
|
|
|
FT_UInt hash = node->glyph_index % gset->hash_size;
|
2000-10-31 21:42:18 +01:00
|
|
|
|
2000-10-31 23:13:54 +01:00
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
/* remove the node from its gset's bucket list */
|
2000-10-28 09:26:59 +02:00
|
|
|
{
|
2000-10-28 15:17:11 +02:00
|
|
|
FTC_GlyphNode* pnode = gset->buckets + hash;
|
2000-10-28 09:26:59 +02:00
|
|
|
FTC_GlyphNode cur;
|
2000-10-31 21:42:18 +01:00
|
|
|
|
2000-10-31 23:13:54 +01:00
|
|
|
|
2000-10-28 09:26:59 +02:00
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
cur = *pnode;
|
2000-10-31 23:13:54 +01:00
|
|
|
if ( !cur )
|
2000-10-28 09:26:59 +02:00
|
|
|
{
|
2000-10-31 23:13:54 +01:00
|
|
|
/* this should never happen */
|
2000-10-28 09:26:59 +02:00
|
|
|
FT_ERROR(( "FTC_GlyphNode_Destroy:"
|
2000-10-31 23:13:54 +01:00
|
|
|
" trying to delete an unlisted node!" ));
|
2000-10-28 09:26:59 +02:00
|
|
|
return;
|
|
|
|
}
|
2000-10-31 21:42:18 +01:00
|
|
|
|
2000-10-31 23:13:54 +01:00
|
|
|
if ( cur == node )
|
2000-10-28 09:26:59 +02:00
|
|
|
{
|
2000-10-28 15:17:11 +02:00
|
|
|
*pnode = cur->gset_next;
|
2000-10-28 09:26:59 +02:00
|
|
|
break;
|
|
|
|
}
|
2000-10-28 15:17:11 +02:00
|
|
|
pnode = &cur->gset_next;
|
2000-10-28 09:26:59 +02:00
|
|
|
}
|
|
|
|
}
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-09-19 03:11:11 +02:00
|
|
|
/* destroy the node */
|
2000-10-28 15:17:11 +02:00
|
|
|
gset->clazz->destroy_node( node, gset );
|
2000-09-19 03:11:11 +02:00
|
|
|
}
|
|
|
|
|
2000-10-12 07:05:40 +02:00
|
|
|
|
|
|
|
/* Important: This function is called from the cache manager to */
|
|
|
|
/* size a given cache node during `cache compression'. The */
|
|
|
|
/* second argument is always `cache.user_data'. Thus be */
|
2000-10-28 09:26:59 +02:00
|
|
|
/* certain that the function FTC_Glyph_Cache_New() does indeed */
|
2000-10-12 07:05:40 +02:00
|
|
|
/* set its `user_data' field correctly, otherwise bad things */
|
|
|
|
/* will happen! */
|
|
|
|
|
2000-11-04 02:55:49 +01:00
|
|
|
FT_EXPORT_DEF( FT_ULong ) FTC_GlyphNode_Size( FTC_GlyphNode node,
|
|
|
|
FTC_Glyph_Cache cache )
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
2000-10-28 15:17:11 +02:00
|
|
|
FT_LruNode gset_lru = cache->gsets_lru->nodes + node->gset_index;
|
|
|
|
FTC_GlyphSet gset = (FTC_GlyphSet)gset_lru->root.data;
|
2000-10-12 07:05:40 +02:00
|
|
|
|
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
return gset->clazz->size_node( node, gset );
|
2000-09-19 03:11:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-11-04 02:55:49 +01:00
|
|
|
FT_CALLBACK_TABLE_DEF
|
|
|
|
const FTC_CacheNode_Class ftc_glyph_cache_node_class =
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
2000-10-31 23:13:54 +01:00
|
|
|
(FTC_CacheNode_SizeFunc) FTC_GlyphNode_Size,
|
|
|
|
(FTC_CacheNode_DestroyFunc)FTC_GlyphNode_Destroy
|
2000-09-19 03:11:11 +02:00
|
|
|
};
|
|
|
|
|
2000-10-12 07:05:40 +02:00
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/***** *****/
|
2000-10-29 01:34:45 +02:00
|
|
|
/***** GLYPH SETS *****/
|
2000-10-12 07:05:40 +02:00
|
|
|
/***** *****/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
2000-11-04 02:55:49 +01:00
|
|
|
FT_EXPORT_DEF( FT_Error ) FTC_GlyphSet_New( FTC_Glyph_Cache cache,
|
|
|
|
FT_Pointer type,
|
|
|
|
FTC_GlyphSet* aset )
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
2000-10-31 23:13:54 +01:00
|
|
|
FT_Error error;
|
|
|
|
FT_Memory memory = cache->root.memory;
|
|
|
|
FTC_Manager manager = cache->root.manager;
|
|
|
|
FTC_GlyphSet gset = 0;
|
2000-10-12 07:05:40 +02:00
|
|
|
|
|
|
|
FTC_Glyph_Cache_Class* gcache_class;
|
2000-10-28 15:17:11 +02:00
|
|
|
FTC_GlyphSet_Class* clazz;
|
2000-10-12 07:05:40 +02:00
|
|
|
|
|
|
|
|
2000-09-19 03:11:11 +02:00
|
|
|
gcache_class = (FTC_Glyph_Cache_Class*)cache->root.clazz;
|
2000-10-28 15:17:11 +02:00
|
|
|
clazz = gcache_class->gset_class;
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
*aset = 0;
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
if ( ALLOC( gset, clazz->gset_byte_size ) )
|
2000-09-19 03:11:11 +02:00
|
|
|
goto Exit;
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
gset->cache = cache;
|
|
|
|
gset->manager = manager;
|
|
|
|
gset->memory = memory;
|
|
|
|
gset->hash_size = FTC_GSET_HASH_SIZE_DEFAULT;
|
|
|
|
gset->clazz = clazz;
|
2000-09-19 03:11:11 +02:00
|
|
|
|
|
|
|
/* allocate buckets table */
|
2000-10-28 15:17:11 +02:00
|
|
|
if ( ALLOC_ARRAY( gset->buckets, gset->hash_size, FTC_GlyphNode ) )
|
2000-09-19 03:11:11 +02:00
|
|
|
goto Exit;
|
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
/* initialize gset by type if needed */
|
2000-10-12 07:05:40 +02:00
|
|
|
if ( clazz->init )
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
2000-10-28 15:17:11 +02:00
|
|
|
error = clazz->init( gset, type );
|
2000-10-12 07:05:40 +02:00
|
|
|
if ( error )
|
2000-09-19 03:11:11 +02:00
|
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
*aset = gset;
|
2000-09-19 03:11:11 +02:00
|
|
|
|
|
|
|
Exit:
|
2000-10-28 15:17:11 +02:00
|
|
|
if ( error && gset )
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
2000-10-28 15:17:11 +02:00
|
|
|
FREE( gset->buckets );
|
|
|
|
FREE( gset );
|
2000-09-19 03:11:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return error;
|
2000-10-12 07:05:40 +02:00
|
|
|
}
|
2000-09-19 03:11:11 +02:00
|
|
|
|
|
|
|
|
2000-11-04 02:55:49 +01:00
|
|
|
FT_EXPORT_DEF( void ) FTC_GlyphSet_Destroy( FTC_GlyphSet gset )
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
2000-10-31 23:13:54 +01:00
|
|
|
FTC_Glyph_Cache cache = gset->cache;
|
|
|
|
FTC_Manager manager = cache->root.manager;
|
|
|
|
FT_List glyphs_lru = &manager->global_lru;
|
|
|
|
FTC_GlyphNode* bucket = gset->buckets;
|
|
|
|
FTC_GlyphNode* bucket_limit = bucket + gset->hash_size;
|
|
|
|
FT_Memory memory = cache->root.memory;
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-10-31 23:13:54 +01:00
|
|
|
FTC_GlyphSet_Class* clazz = gset->clazz;
|
2000-09-19 03:11:11 +02:00
|
|
|
|
2000-10-12 07:05:40 +02:00
|
|
|
|
|
|
|
/* for each bucket, free the list of glyph nodes */
|
2000-09-19 03:11:11 +02:00
|
|
|
for ( ; bucket < bucket_limit; bucket++ )
|
|
|
|
{
|
2000-10-28 09:26:59 +02:00
|
|
|
FTC_GlyphNode node = bucket[0];
|
|
|
|
FTC_GlyphNode next = 0;
|
|
|
|
FT_ListNode lrunode;
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-09-19 03:11:11 +02:00
|
|
|
|
|
|
|
for ( ; node; node = next )
|
|
|
|
{
|
2000-10-28 15:17:11 +02:00
|
|
|
next = node->gset_next;
|
2000-10-28 09:26:59 +02:00
|
|
|
lrunode = FTC_GLYPHNODE_TO_LRUNODE( node );
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
manager->num_bytes -= clazz->size_node( node, gset );
|
2000-10-31 23:13:54 +01:00
|
|
|
manager->num_nodes--;
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-09-19 03:11:11 +02:00
|
|
|
FT_List_Remove( glyphs_lru, lrunode );
|
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
clazz->destroy_node( node, gset );
|
2000-09-19 03:11:11 +02:00
|
|
|
}
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-10-28 09:26:59 +02:00
|
|
|
bucket[0] = 0;
|
2000-09-19 03:11:11 +02:00
|
|
|
}
|
|
|
|
|
2000-10-12 07:05:40 +02:00
|
|
|
if ( clazz->done )
|
2000-10-28 15:17:11 +02:00
|
|
|
clazz->done( gset );
|
2000-09-19 03:11:11 +02:00
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
FREE( gset->buckets );
|
|
|
|
FREE( gset );
|
2000-09-19 03:11:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-11-04 02:55:49 +01:00
|
|
|
FT_EXPORT_DEF( FT_Error ) FTC_GlyphSet_Lookup_Node(
|
2000-11-04 09:33:38 +01:00
|
|
|
FTC_GlyphSet gset,
|
|
|
|
FT_UInt glyph_index,
|
|
|
|
FTC_GlyphNode* anode )
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
2000-10-31 23:13:54 +01:00
|
|
|
FTC_Glyph_Cache cache = gset->cache;
|
|
|
|
FTC_Manager manager = cache->root.manager;
|
|
|
|
FT_UInt hash_index = glyph_index % gset->hash_size;
|
|
|
|
FTC_GlyphNode* bucket = gset->buckets + hash_index;
|
|
|
|
FTC_GlyphNode* pnode = bucket;
|
|
|
|
FTC_GlyphNode node;
|
|
|
|
FT_Error error;
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-10-31 23:13:54 +01:00
|
|
|
FTC_GlyphSet_Class* clazz = gset->clazz;
|
2000-09-19 03:11:11 +02:00
|
|
|
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-09-19 03:11:11 +02:00
|
|
|
*anode = 0;
|
2000-10-31 21:42:18 +01:00
|
|
|
|
2000-10-28 09:26:59 +02:00
|
|
|
for ( ;; )
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
2000-10-28 09:26:59 +02:00
|
|
|
node = *pnode;
|
2000-10-31 23:13:54 +01:00
|
|
|
if ( !node )
|
2000-10-28 09:26:59 +02:00
|
|
|
break;
|
2000-10-31 21:42:18 +01:00
|
|
|
|
2000-10-28 09:26:59 +02:00
|
|
|
if ( node->glyph_index == glyph_index )
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
|
|
|
/* we found it! -- move glyph to start of the lists */
|
2000-10-28 15:17:11 +02:00
|
|
|
*pnode = node->gset_next;
|
|
|
|
node->gset_next = bucket[0];
|
|
|
|
bucket[0] = node;
|
2000-10-31 21:42:18 +01:00
|
|
|
|
2000-10-28 09:26:59 +02:00
|
|
|
FT_List_Up( &manager->global_lru, FTC_GLYPHNODE_TO_LRUNODE( node ) );
|
|
|
|
*anode = node;
|
2000-09-19 03:11:11 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2000-10-28 09:26:59 +02:00
|
|
|
/* go to next node in bucket */
|
2000-10-28 15:17:11 +02:00
|
|
|
pnode = &node->gset_next;
|
2000-09-19 03:11:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* we didn't found the glyph image, we will now create a new one */
|
2000-10-28 15:17:11 +02:00
|
|
|
error = clazz->new_node( gset, glyph_index, &node );
|
2000-09-19 03:11:11 +02:00
|
|
|
if ( error )
|
|
|
|
goto Exit;
|
|
|
|
|
|
|
|
/* insert the node at the start of our bucket list */
|
2000-10-28 15:17:11 +02:00
|
|
|
node->gset_next = bucket[0];
|
|
|
|
bucket[0] = node;
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-09-19 03:11:11 +02:00
|
|
|
/* insert the node at the start the global LRU glyph list */
|
2000-10-28 09:26:59 +02:00
|
|
|
FT_List_Insert( &manager->global_lru, FTC_GLYPHNODE_TO_LRUNODE( node ) );
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
manager->num_bytes += clazz->size_node( node, gset );
|
2000-10-31 23:13:54 +01:00
|
|
|
manager->num_nodes++;
|
2000-09-19 03:11:11 +02:00
|
|
|
|
2000-10-31 23:13:54 +01:00
|
|
|
if ( manager->num_bytes > manager->max_bytes )
|
2000-10-28 15:17:11 +02:00
|
|
|
{
|
|
|
|
FTC_GlyphNode_Ref ( node );
|
2000-09-19 03:11:11 +02:00
|
|
|
FTC_Manager_Compress( manager );
|
2000-10-28 15:17:11 +02:00
|
|
|
FTC_GlyphNode_Unref ( node );
|
|
|
|
}
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-10-28 09:26:59 +02:00
|
|
|
*anode = node;
|
2000-09-19 03:11:11 +02:00
|
|
|
|
|
|
|
Exit:
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-09-19 03:11:11 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/***** *****/
|
2000-10-28 15:17:11 +02:00
|
|
|
/***** GLYPH SETS LRU CALLBACKS *****/
|
2000-09-19 03:11:11 +02:00
|
|
|
/***** *****/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-09-19 03:11:11 +02:00
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
#define FTC_GSET_LRU_GET_CACHE( lru ) \
|
2000-09-19 03:11:11 +02:00
|
|
|
( (FTC_Glyph_Cache)(lru)->user_data )
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
#define FTC_GSET_LRU_GET_MANAGER( lru ) \
|
|
|
|
FTC_GSET_LRU_GET_CACHE( lru )->manager
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
#define FTC_LRUNODE_GSET( node ) \
|
|
|
|
( (FTC_GlyphSet)(node)->root.data )
|
2000-09-19 03:11:11 +02:00
|
|
|
|
|
|
|
|
2000-11-04 02:55:49 +01:00
|
|
|
FT_CALLBACK_DEF
|
2000-10-28 15:17:11 +02:00
|
|
|
FT_Error ftc_glyph_set_lru_init( FT_Lru lru,
|
|
|
|
FT_LruNode node )
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
2000-10-28 15:17:11 +02:00
|
|
|
FTC_Glyph_Cache cache = FTC_GSET_LRU_GET_CACHE( lru );
|
2000-09-19 03:11:11 +02:00
|
|
|
FT_Error error;
|
2000-10-28 15:17:11 +02:00
|
|
|
FTC_GlyphSet gset;
|
2000-09-19 03:11:11 +02:00
|
|
|
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
error = FTC_GlyphSet_New( cache, (FT_Pointer)node->key, &gset );
|
2000-09-19 03:11:11 +02:00
|
|
|
if ( !error )
|
|
|
|
{
|
2000-10-28 15:17:11 +02:00
|
|
|
/* good, now set the gset index within the gset object */
|
|
|
|
gset->gset_index = node - lru->nodes;
|
|
|
|
node->root.data = gset;
|
2000-09-19 03:11:11 +02:00
|
|
|
}
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-09-19 03:11:11 +02:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-11-04 02:55:49 +01:00
|
|
|
FT_CALLBACK_DEF
|
2000-10-28 15:17:11 +02:00
|
|
|
void ftc_glyph_set_lru_done( FT_Lru lru,
|
|
|
|
FT_LruNode node )
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
2000-10-28 15:17:11 +02:00
|
|
|
FTC_GlyphSet gset = FTC_LRUNODE_GSET( node );
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-09-19 03:11:11 +02:00
|
|
|
FT_UNUSED( lru );
|
|
|
|
|
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
FTC_GlyphSet_Destroy( gset );
|
2000-09-19 03:11:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-11-04 02:55:49 +01:00
|
|
|
FT_CALLBACK_DEF
|
2000-10-28 15:17:11 +02:00
|
|
|
FT_Bool ftc_glyph_set_lru_compare( FT_LruNode node,
|
|
|
|
FT_LruKey key )
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
2000-10-28 15:17:11 +02:00
|
|
|
FTC_GlyphSet gset = FTC_LRUNODE_GSET( node );
|
2000-09-19 03:11:11 +02:00
|
|
|
|
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
return gset->clazz->compare( gset, (FT_Pointer)key );
|
2000-10-12 07:05:40 +02:00
|
|
|
}
|
|
|
|
|
2000-09-19 03:11:11 +02:00
|
|
|
|
2000-11-04 02:55:49 +01:00
|
|
|
FT_CALLBACK_TABLE_DEF
|
|
|
|
const FT_Lru_Class ftc_glyph_set_lru_class =
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
|
|
|
sizeof( FT_LruRec ),
|
2000-10-28 15:17:11 +02:00
|
|
|
ftc_glyph_set_lru_init,
|
|
|
|
ftc_glyph_set_lru_done,
|
2000-09-19 03:11:11 +02:00
|
|
|
0, /* no flush */
|
2000-10-28 15:17:11 +02:00
|
|
|
ftc_glyph_set_lru_compare
|
2000-09-19 03:11:11 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/***** *****/
|
2000-10-29 01:34:45 +02:00
|
|
|
/***** GLYPH CACHE OBJECTS *****/
|
2000-09-19 03:11:11 +02:00
|
|
|
/***** *****/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
|
2000-10-12 07:05:40 +02:00
|
|
|
|
2000-11-06 20:29:06 +01:00
|
|
|
FT_EXPORT_DEF( FT_Error )
|
|
|
|
FTC_Glyph_Cache_Init( FTC_Glyph_Cache cache )
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
2000-10-12 07:05:40 +02:00
|
|
|
FT_Memory memory = cache->root.memory;
|
|
|
|
FT_Error error;
|
|
|
|
|
2000-11-06 20:29:06 +01:00
|
|
|
FTC_Glyph_Cache_Class* gcache_clazz;
|
2000-09-19 03:11:11 +02:00
|
|
|
|
|
|
|
/* set up root node_class to be used by manager */
|
2000-10-12 07:05:40 +02:00
|
|
|
cache->root.node_clazz =
|
|
|
|
(FTC_CacheNode_Class*)&ftc_glyph_cache_node_class;
|
|
|
|
|
2000-11-06 20:29:06 +01:00
|
|
|
/* setup the "compare" shortcut */
|
|
|
|
gcache_clazz = (FTC_Glyph_Cache_Class*)cache->root.clazz;
|
|
|
|
cache->compare = gcache_clazz->gset_class->compare;
|
|
|
|
|
2000-10-12 07:05:40 +02:00
|
|
|
/* The following is extremely important for ftc_destroy_glyph_image() */
|
|
|
|
/* to work properly, as the second parameter that is sent to it */
|
2000-10-29 01:34:45 +02:00
|
|
|
/* through the cache manager is `cache_data' and must be set to */
|
2000-10-12 07:05:40 +02:00
|
|
|
/* `cache' here. */
|
|
|
|
/* */
|
2000-10-29 01:34:45 +02:00
|
|
|
cache->root.cache_data = cache;
|
2000-09-19 03:11:11 +02:00
|
|
|
|
2000-10-28 15:17:11 +02:00
|
|
|
error = FT_Lru_New( &ftc_glyph_set_lru_class,
|
|
|
|
FTC_MAX_GLYPH_SETS,
|
2000-09-19 03:11:11 +02:00
|
|
|
cache,
|
|
|
|
memory,
|
|
|
|
1, /* pre_alloc == TRUE */
|
2000-10-28 15:17:11 +02:00
|
|
|
&cache->gsets_lru );
|
2000-09-19 03:11:11 +02:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-11-06 20:29:06 +01:00
|
|
|
FT_EXPORT_DEF( void )
|
|
|
|
FTC_Glyph_Cache_Done( FTC_Glyph_Cache cache )
|
2000-09-19 03:11:11 +02:00
|
|
|
{
|
2000-10-28 15:17:11 +02:00
|
|
|
/* discard glyph sets */
|
|
|
|
FT_Lru_Done( cache->gsets_lru );
|
2000-09-19 03:11:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-11-06 20:29:06 +01:00
|
|
|
FT_EXPORT_DEF( FT_Error )
|
|
|
|
FTC_Glyph_Cache_Lookup( FTC_Glyph_Cache cache,
|
|
|
|
FT_Pointer type,
|
|
|
|
FT_UInt gindex,
|
|
|
|
FTC_GlyphNode *anode )
|
|
|
|
{
|
|
|
|
FT_Error error;
|
|
|
|
FTC_GlyphSet gset;
|
|
|
|
FTC_GlyphNode node;
|
|
|
|
FTC_Manager manager;
|
|
|
|
|
|
|
|
/* check for valid `desc' delayed to FT_Lru_Lookup() */
|
|
|
|
|
|
|
|
if ( !cache || !anode )
|
|
|
|
return FT_Err_Invalid_Argument;
|
|
|
|
|
|
|
|
*anode = 0;
|
|
|
|
gset = cache->last_gset;
|
|
|
|
if ( !gset || !cache->compare( gset, type ) )
|
|
|
|
{
|
|
|
|
error = FT_Lru_Lookup( cache->gsets_lru,
|
|
|
|
(FT_LruKey)type,
|
|
|
|
(FT_Pointer*)&gset );
|
|
|
|
cache->last_gset = gset;
|
|
|
|
if ( error )
|
|
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = FTC_GlyphSet_Lookup_Node( gset, gindex, &node );
|
|
|
|
if ( error )
|
|
|
|
goto Exit;
|
|
|
|
|
|
|
|
/* now compress the manager's cache pool if needed */
|
|
|
|
manager = cache->root.manager;
|
|
|
|
if ( manager->num_bytes > manager->max_bytes )
|
|
|
|
{
|
|
|
|
FTC_GlyphNode_Ref ( node );
|
|
|
|
FTC_Manager_Compress( manager );
|
|
|
|
FTC_GlyphNode_Unref ( node );
|
|
|
|
}
|
|
|
|
|
|
|
|
*anode = node;
|
|
|
|
|
|
|
|
Exit:
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2000-09-19 03:11:11 +02:00
|
|
|
/* END */
|