diff options
author | David Turner <david@freetype.org> | 2000-09-19 01:11:11 +0000 |
---|---|---|
committer | David Turner <david@freetype.org> | 2000-09-19 01:11:11 +0000 |
commit | ebdce8344a089963635473c73cb7cbc967bc6a7e (patch) | |
tree | 4b0454128443c6a4cd2dfb2b9aedfea7a367389f /src | |
parent | 58e932157b02295427db073e19a36cbae33213e6 (diff) |
updated the cache sub-system. Major internal rewrite
please be aware that major bug persist..
Diffstat (limited to 'src')
-rw-r--r-- | src/cache/ftcache.c | 2 | ||||
-rw-r--r-- | src/cache/ftcglyph.c | 386 | ||||
-rw-r--r-- | src/cache/ftcimage.c | 609 | ||||
-rw-r--r-- | src/cache/ftcimage.h | 134 | ||||
-rw-r--r-- | src/cache/ftcmanag.c | 171 | ||||
-rw-r--r-- | src/cache/ftlru.c | 2 | ||||
-rw-r--r-- | src/cache/rules.mk | 24 |
7 files changed, 701 insertions, 627 deletions
diff --git a/src/cache/ftcache.c b/src/cache/ftcache.c index cdd78997..913dba4a 100644 --- a/src/cache/ftcache.c +++ b/src/cache/ftcache.c @@ -22,12 +22,14 @@ #include "ftlru.c" #include "ftcmanag.c" +#include "ftcglyph.c" #include "ftcimage.c" #else #include <cache/ftlru.c> #include <cache/ftcmanag.c> +#include <cache/ftcglyph.c> #include <cache/ftcimage.c> #endif diff --git a/src/cache/ftcglyph.c b/src/cache/ftcglyph.c new file mode 100644 index 00000000..c7d74639 --- /dev/null +++ b/src/cache/ftcglyph.c @@ -0,0 +1,386 @@ +/***************************************************************************/ +/* */ +/* ftcglyph.c */ +/* */ +/* FreeType Glyph Image (FT_Glyph) cache.. */ +/* */ +/* 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. */ +/* */ +/* */ +/* Note: the implementation of glyph queues is rather generic in this */ +/* code. This will allow other glyph node/cache types to be */ +/* easily included in the future.. For now, we only cache */ +/* glyph images.. */ +/* */ +/***************************************************************************/ + + +#include <freetype/cache/ftcglyph.h> +#include <freetype/fterrors.h> +#include <freetype/internal/ftobjs.h> +#include <freetype/internal/ftlist.h> +#include <freetype/fterrors.h> + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH NODES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +/* in the future, we might provide a better scheme for managing */ +/* glyph node element. For the moment, we simply use FT_Alloc/FT_Free */ + + /* creates a new glyph node, setting its cache index and ref count */ + FT_EXPORT_FUNC(void) FTC_GlyphNode_Init( FTC_GlyphNode node, + FTC_Glyph_Queue queue, + FT_UInt gindex ) + { + FTC_Glyph_Cache cache = queue->cache; + FTC_CacheNode_Data* data = FTC_CACHENODE_TO_DATA_P( &node->root ); + + data->cache_index = (FT_UShort) cache->root.cache_index; + data->ref_count = (FT_Short) 0; + node->queue_index = (FT_UShort) queue->queue_index; + node->glyph_index = (FT_UShort) gindex; + } + + + + + /* Important: this function is called from the cache manager to */ + /* destroy a given cache node during "cache compression". The */ + /* second argument is always "cache.user_data". You thus be */ + /* certain that the function FTC_Image_Cache_New does indeed */ + /* set its "user_data" field correctly, otherwise bad things */ + /* will happen !! */ + + FT_EXPORT_FUNC(void) FTC_GlyphNode_Destroy( FTC_GlyphNode node, + FTC_Glyph_Cache cache ) + { + FT_LruNode queue_lru = cache->queues_lru->nodes+node->queue_index; + FTC_Glyph_Queue queue = (FTC_Glyph_Queue)queue_lru->root.data; + FT_UInt hash = node->glyph_index % queue->hash_size; + FT_List bucket = queue->buckets + hash; + + /* remove node from its queue's bucket list */ + FT_List_Remove( bucket, FTC_GLYPHNODE_TO_LISTNODE(node) ); + + /* destroy the node */ + queue->clazz->destroy_node( node, queue ); + } + + + /* 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". You thus be */ + /* certain that the function FTC_Image_Cache_New does indeed */ + /* set its "user_data" field correctly, otherwise bad things */ + /* will happen !! */ + + FT_EXPORT_FUNC(FT_ULong) FTC_GlyphNode_Size( FTC_GlyphNode node, + FTC_Glyph_Cache cache ) + { + FT_LruNode queue_lru = cache->queues_lru->nodes+node->queue_index; + FTC_Glyph_Queue queue = (FTC_Glyph_Queue)queue_lru->root.data; + + return queue->clazz->size_node( node, queue ); + } + + + FT_CPLUSPLUS(const FTC_CacheNode_Class) ftc_glyph_cache_node_class = + { + (FTC_CacheNode_SizeFunc) FTC_GlyphNode_Size, + (FTC_CacheNode_DestroyFunc) FTC_GlyphNode_Destroy + }; + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH QUEUES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_EXPORT_FUNC(FT_Error) FTC_Glyph_Queue_New( + FTC_Glyph_Cache cache, + FT_Pointer type, + FTC_Glyph_Queue* aqueue ) + { + FT_Error error; + FT_Memory memory = cache->root.memory; + FTC_Manager manager = cache->root.manager; + FTC_Glyph_Queue queue = 0; + + FTC_Glyph_Cache_Class* gcache_class; + FTC_Glyph_Queue_Class* clazz; + + gcache_class = (FTC_Glyph_Cache_Class*)cache->root.clazz; + clazz = gcache_class->queue_class; + + *aqueue = 0; + + if ( ALLOC( queue, clazz->queue_byte_size ) ) + goto Exit; + + queue->cache = cache; + queue->manager = manager; + queue->memory = memory; + queue->hash_size = FTC_QUEUE_HASH_SIZE_DEFAULT; + queue->clazz = clazz; + + /* allocate buckets table */ + if ( ALLOC_ARRAY( queue->buckets, queue->hash_size, FT_ListRec ) ) + if (error) + goto Exit; + + /* initialize queue by type - if needed */ + if (clazz->init) + { + error = clazz->init( queue, type ); + if (error) + goto Exit; + } + + *aqueue = queue; + + Exit: + if ( error && queue ) + { + FREE( queue->buckets ); + FREE( queue ); + } + + return error; + } + + + + FT_EXPORT_FUNC(void) FTC_Glyph_Queue_Done( FTC_Glyph_Queue queue ) + { + FTC_Glyph_Cache cache = queue->cache; + FTC_Manager manager = cache->root.manager; + FT_List glyphs_lru = &manager->global_lru; + FT_List bucket = queue->buckets; + FT_List bucket_limit = bucket + queue->hash_size; + FT_Memory memory = cache->root.memory; + + FTC_Glyph_Queue_Class* clazz = queue->clazz; + + /* for each bucket, free the list of Glyph nodes */ + for ( ; bucket < bucket_limit; bucket++ ) + { + FT_ListNode node = bucket->head; + FT_ListNode next = 0; + FT_ListNode lrunode; + FTC_GlyphNode inode; + + + for ( ; node; node = next ) + { + next = node->next; + inode = FTC_LISTNODE_TO_GLYPHNODE(node); + lrunode = FTC_GLYPHNODE_TO_LRUNODE( inode ); + + manager->num_bytes -= clazz->size_node( inode, queue ); + + FT_List_Remove( glyphs_lru, lrunode ); + + clazz->destroy_node( inode, queue ); + } + + bucket->head = bucket->tail = 0; + } + + if (clazz->done) + clazz->done(queue); + + FREE( queue->buckets ); + FREE( queue ); + } + + + FT_EXPORT_FUNC(FT_Error) FTC_Glyph_Queue_Lookup_Node( + FTC_Glyph_Queue queue, + FT_UInt glyph_index, + FTC_GlyphNode* anode ) + { + FTC_Glyph_Cache cache = queue->cache; + FTC_Manager manager = cache->root.manager; + FT_UInt hash_index = glyph_index % queue->hash_size; + FT_List bucket = queue->buckets + hash_index; + FT_ListNode node; + FT_Error error; + FTC_GlyphNode inode; + + FTC_Glyph_Queue_Class* clazz = queue->clazz; + + *anode = 0; + for ( node = bucket->head; node; node = node->next ) + { + FT_UInt gindex; + + inode = FTC_LISTNODE_TO_GLYPHNODE(node); + gindex = inode->glyph_index; + + if ( gindex == glyph_index ) + { + /* we found it! -- move glyph to start of the lists */ + FT_List_Up( bucket, node ); + FT_List_Up( &manager->global_lru, FTC_GLYPHNODE_TO_LRUNODE( inode ) ); + *anode = inode; + return 0; + } + } + + /* we didn't found the glyph image, we will now create a new one */ + error = clazz->new_node( queue, glyph_index, &inode ); + if ( error ) + goto Exit; + + /* insert the node at the start of our bucket list */ + FT_List_Insert( bucket, FTC_GLYPHNODE_TO_LISTNODE(inode) ); + + /* insert the node at the start the global LRU glyph list */ + FT_List_Insert( &manager->global_lru, FTC_GLYPHNODE_TO_LRUNODE(inode) ); + + manager->num_bytes += clazz->size_node( inode, queue ); + + if (manager->num_bytes > manager->max_bytes) + FTC_Manager_Compress( manager ); + + *anode = inode; + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH QUEUES LRU CALLBACKS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + +#define FTC_QUEUE_LRU_GET_CACHE( lru ) \ + ( (FTC_Glyph_Cache)(lru)->user_data ) + +#define FTC_QUEUE_LRU_GET_MANAGER( lru ) \ + FTC_QUEUE_LRU_GET_CACHE( lru )->manager + +#define FTC_LRUNODE_QUEUE( node ) \ + ( (FTC_Glyph_Queue)(node)->root.data ) + + + LOCAL_FUNC_X + FT_Error ftc_glyph_queue_lru_init( FT_Lru lru, + FT_LruNode node ) + { + FTC_Glyph_Cache cache = FTC_QUEUE_LRU_GET_CACHE( lru ); + FT_Error error; + FTC_Glyph_Queue queue; + + error = FTC_Glyph_Queue_New( cache, + (FT_Pointer)node->key, + &queue ); + if ( !error ) + { + /* good, now set the queue index within the queue object */ + queue->queue_index = node - lru->nodes; + node->root.data = queue; + } + + return error; + } + + + + LOCAL_FUNC_X + void ftc_glyph_queue_lru_done( FT_Lru lru, + FT_LruNode node ) + { + FTC_Glyph_Queue queue = FTC_LRUNODE_QUEUE( node ); + + FT_UNUSED( lru ); + + + FTC_Glyph_Queue_Done( queue ); + } + + + + LOCAL_FUNC_X + FT_Bool ftc_glyph_queue_lru_compare( FT_LruNode node, + FT_LruKey key ) + { + FTC_Glyph_Queue queue = FTC_LRUNODE_QUEUE( node ); + return queue->clazz->compare( queue, (FT_Pointer)key ); + } + + + + FT_CPLUSPLUS( const FT_Lru_Class ) ftc_glyph_queue_lru_class = + { + sizeof( FT_LruRec ), + ftc_glyph_queue_lru_init, + ftc_glyph_queue_lru_done, + 0, /* no flush */ + ftc_glyph_queue_lru_compare + }; + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH IMAGE CACHE OBJECTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_EXPORT_FUNC(FT_Error) FTC_Glyph_Cache_Init( FTC_Glyph_Cache cache ) + { + FT_Memory memory = cache->root.memory; + FT_Error error; + + /* set up root node_class to be used by manager */ + cache->root.node_clazz = (FTC_CacheNode_Class*)&ftc_glyph_cache_node_class; + + /* The following is extremely important for ftc_destroy_glyph_image */ + /* to work properly, as the second parameter that is sent to it */ + /* through the cache manager is "user_data" and must be set to */ + /* "cache" here.. */ + /* */ + cache->root.cache_user = cache; + + error = FT_Lru_New( &ftc_glyph_queue_lru_class, + FTC_MAX_GLYPH_QUEUES, + cache, + memory, + 1, /* pre_alloc == TRUE */ + &cache->queues_lru ); + return error; + } + + + FT_EXPORT_FUNC(void) FTC_Glyph_Cache_Done( FTC_Glyph_Cache cache ) + { + /* discard Glyph queues */ + FT_Lru_Done( cache->queues_lru ); + } + + + +/* END */ diff --git a/src/cache/ftcimage.c b/src/cache/ftcimage.c index 5ea6ea37..5f044e06 100644 --- a/src/cache/ftcimage.c +++ b/src/cache/ftcimage.c @@ -1,146 +1,58 @@ -/***************************************************************************/ -/* */ -/* ftcimage.c */ -/* */ -/* FreeType Image Cache (body). */ -/* */ -/* 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 <cache/ftcimage.h> -#include <freetype/fterrors.h> -#include <freetype/internal/ftobjs.h> -#include <freetype/internal/ftlist.h> -#include <freetype/fterrors.h> - - - /**************************************************************************/ - /**************************************************************************/ - /***** *****/ - /***** IMAGE NODE MANAGEMENT *****/ - /***** *****/ - /***** For now, we simply ALLOC/FREE the FTC_ImageNode. However, it *****/ - /***** certainly is a good idea to use a chunk manager in the future *****/ - /***** in order to reduce memory waste resp. fragmentation. *****/ - /***** *****/ - /**************************************************************************/ - /**************************************************************************/ +#ifdef FT_FLAT_COMPILE +# include "ftcimage.h" +#else +# include <cache/ftcimage.h> +#endif + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH IMAGE NODES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ - - static - FT_Error FTC_ImageNode_New( FTC_Image_Cache cache, - FTC_ImageNode* anode ) - { - FT_Error error; - FT_Memory memory = cache->memory; - FTC_ImageNode node; - - - *anode = 0; - if ( !ALLOC( node, sizeof ( *node ) ) ) - *anode = node; - - return error; - } - - - static - void FTC_ImageNode_Done( FTC_Image_Cache cache, - FTC_ImageNode node ) - { - /* for now, we simply discard the node; we may later add a chunk */ - /* manager to the image cache. */ - FT_Memory memory = cache->memory; - - - FREE( node ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GLYPH IMAGE QUEUES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - + /* this is a simple glyph image destructor, which is called exclusively */ + /* from the CacheQueue object */ LOCAL_FUNC_X - void ftc_done_glyph_image( FTC_Image_Queue queue, - FTC_ImageNode node ) + void ftc_glyph_image_node_destroy( FTC_GlyphNode node, + FTC_Glyph_Queue queue ) { - FT_UNUSED( queue ); - - FT_Done_Glyph( FTC_IMAGENODE_GET_GLYPH( node ) ); - } - - - LOCAL_FUNC_X - FT_ULong ftc_size_bitmap_image( FTC_Image_Queue queue, - FTC_ImageNode node ) - { - FT_Long pitch; - FT_BitmapGlyph glyph; - - FT_UNUSED( queue ); - - - glyph = (FT_BitmapGlyph)FTC_IMAGENODE_GET_GLYPH(node); - pitch = glyph->bitmap.pitch; - if ( pitch < 0 ) - pitch = -pitch; - - return (FT_ULong)(pitch * glyph->bitmap.rows + sizeof ( *glyph ) ); - } - - - LOCAL_FUNC_X - FT_ULong ftc_size_outline_image( FTC_Image_Queue queue, - FTC_ImageNode node ) - { - FT_OutlineGlyph glyph; - FT_Outline* outline; + FT_Memory memory = queue->memory; - FT_UNUSED( queue ); - - - glyph = (FT_OutlineGlyph)FTC_IMAGENODE_GET_GLYPH( node ); - outline = &glyph->outline; - - return (FT_ULong)( - outline->n_points * ( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) + - outline->n_contours * sizeof ( FT_Short ) + - sizeof( *glyph ) ); + FT_Done_Glyph( FTC_GLYPHNODE_GET_GLYPH( node ) ); + FREE( node ); } LOCAL_FUNC_X - FT_Error ftc_init_glyph_image( FTC_Image_Queue queue, - FTC_ImageNode node ) + FT_Error ftc_glyph_image_node_new( FTC_Glyph_Queue queue, + FT_UInt glyph_index, + FTC_GlyphNode *anode ) { - FT_Face face; - FT_Size size; - FT_Error error; + FT_Memory memory = queue->memory; + FTC_Image_Queue imageq = (FTC_Image_Queue)queue; + FT_Error error; + FTC_GlyphNode node = 0; + FT_Face face; + FT_Size size; + /* allocate node */ + if ( ALLOC( node, sizeof(*node) ) ) + goto Exit; + + /* init its inner fields */ + FTC_GlyphNode_Init( node, queue, glyph_index ); + /* we will now load the glyph image */ error = FTC_Manager_Lookup_Size( queue->manager, - &queue->descriptor.size, + &imageq->description.font, &face, &size ); if ( !error ) { - FT_UInt glyph_index = FTC_IMAGENODE_GET_GINDEX( node ); + FT_UInt glyph_index = node->glyph_index; FT_UInt load_flags = FT_LOAD_DEFAULT; - FT_UInt image_type = queue->descriptor.image_type; + FT_UInt image_type = imageq->description.image_type; if ( FTC_IMAGE_FORMAT( image_type ) == ftc_image_format_bitmap ) { @@ -179,372 +91,133 @@ error = FT_Get_Glyph( face->glyph, &glyph ); if ( !error ) - FTC_IMAGENODE_SET_GLYPH( node, glyph ); + FTC_GLYPHNODE_SET_GLYPH( node, glyph ); } else error = FT_Err_Invalid_Argument; } } - return error; - } - - - FT_CPLUSPLUS( const FTC_Image_Class ) ftc_bitmap_image_class = - { - ftc_init_glyph_image, - ftc_done_glyph_image, - ftc_size_bitmap_image - }; - - FT_CPLUSPLUS( const FTC_Image_Class ) ftc_outline_image_class = - { - ftc_init_glyph_image, - ftc_done_glyph_image, - ftc_size_outline_image - }; - - - static - FT_Error FTC_Image_Queue_New( FTC_Image_Cache cache, - FTC_Image_Desc* desc, - FTC_Image_Queue* aqueue ) - { - FT_Error error; - FT_Memory memory = cache->memory; - FTC_Manager manager = cache->manager; - FTC_Image_Queue queue = 0; - - const FTC_Image_Class* clazz; - - - *aqueue = 0; - if ( ALLOC( queue, sizeof ( *queue ) ) ) - goto Exit; - - queue->cache = cache; - queue->manager = manager; - queue->memory = memory; - queue->descriptor = *desc; - queue->hash_size = 64; - - if ( ALLOC_ARRAY( queue->buckets, queue->hash_size, FT_ListRec ) ) - goto Exit; - - switch ( FTC_IMAGE_FORMAT( desc->image_type ) ) - { - case ftc_image_format_bitmap: - clazz = &ftc_bitmap_image_class; - break; - - case ftc_image_format_outline: - clazz = &ftc_outline_image_class; - break; - - default: - /* invalid image type! */ - error = FT_Err_Invalid_Argument; - goto Exit; - } - - queue->clazz = (FTC_Image_Class*)clazz; - *aqueue = queue; - Exit: - if ( error ) - FREE( queue ); + if (error && node) + FREE(node); + *anode = node; return error; - } + } - static - void FTC_Image_Queue_Done( FTC_Image_Queue queue ) + /* this function is important, because it is both part of */ + /* a FTC_Glyph_Queue_Class and a FTC_CacheNode_Class */ + /* */ + LOCAL_FUNC_X + FT_ULong ftc_glyph_image_node_size( FTC_GlyphNode node ) { - FTC_Image_Cache cache = queue->cache; - FT_List glyphs_lru = &cache->glyphs_lru; - FT_List bucket = queue->buckets; - FT_List bucket_limit = bucket + queue->hash_size; - FT_Memory memory = cache->memory; + FT_ULong size = 0; + FT_Glyph glyph = FTC_GLYPHNODE_GET_GLYPH(node); - - /* for each bucket, free the list of image nodes */ - for ( ; bucket < bucket_limit; bucket++ ) + switch (glyph->format) { - FT_ListNode node = bucket->head; - FT_ListNode next = 0; - FT_ListNode lrunode; - FTC_ImageNode inode; - - - for ( ; node; node = next ) - { - next = node->next; - inode = (FTC_ImageNode)node; - lrunode = FTC_IMAGENODE_TO_LISTNODE( inode ); - - cache->num_bytes -= queue->clazz->size_image( queue, inode ) + - sizeof( FTC_ImageNodeRec ); + case ft_glyph_format_bitmap: + { + FT_BitmapGlyph bitg; + + bitg = (FT_BitmapGlyph)glyph; + size = bitg->bitmap.rows * labs(bitg->bitmap.pitch) + + sizeof(*bitg); + } + break; - queue->clazz->done_image( queue, inode ); - FT_List_Remove( glyphs_lru, lrunode ); + case ft_glyph_format_outline: + { + FT_OutlineGlyph outg; + + outg = (FT_OutlineGlyph)glyph; + size = outg->outline.n_points * + ( sizeof( FT_Vector ) + sizeof( FT_Byte ) ) + + outg->outline.n_contours * + sizeof( FT_Short ) + + sizeof(*outg); + } + break; - FTC_ImageNode_Done( cache, inode ); - } - - bucket->head = bucket->tail = 0; - } - - FREE( queue->buckets ); - FREE( queue ); - } - - - static - FT_Error FTC_Image_Queue_Lookup_Node( FTC_Image_Queue queue, - FT_UInt glyph_index, - FTC_ImageNode* anode ) - { - FTC_Image_Cache cache = queue->cache; - FT_UInt hash_index = glyph_index % queue->hash_size; - FT_List bucket = queue->buckets + hash_index; - FT_ListNode node; - FT_Error error; - FTC_ImageNode inode; - - - *anode = 0; - for ( node = bucket->head; node; node = node->next ) - { - FT_UInt gindex; - - inode = (FTC_ImageNode)node; - gindex = FTC_IMAGENODE_GET_GINDEX( inode ); - - if ( gindex == glyph_index ) - { - /* we found it! -- move glyph to start of the list */ - FT_List_Up( bucket, node ); - FT_List_Up( &cache->glyphs_lru, FTC_IMAGENODE_TO_LISTNODE( inode ) ); - *anode = inode; - return 0; - } - } - - /* we didn't found the glyph image, we will now create a new one */ - error = FTC_ImageNode_New( queue->cache, &inode ); - if ( error ) - goto Exit; - - /* set the glyph and queue indices in the image node */ - FTC_IMAGENODE_SET_INDICES( inode, glyph_index, queue->index ); - - error = queue->clazz->init_image( queue, inode ); - if ( error ) - { - FTC_ImageNode_Done( queue->cache, inode ); - goto Exit; + default: + ; } - - /* insert the node at the start of our bucket list */ - FT_List_Insert( bucket, (FT_ListNode)inode ); - - /* insert the node at the start the global LRU glyph list */ - FT_List_Insert( &cache->glyphs_lru, FTC_IMAGENODE_TO_LISTNODE( inode ) ); - - cache->num_bytes += queue->clazz->size_image( queue, inode ) + - sizeof( FTC_ImageNodeRec ); - - *anode = inode; - - Exit: - return error; + size += sizeof(*node); + return size; } - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** IMAGE CACHE CALLBACKS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define FTC_QUEUE_LRU_GET_CACHE( lru ) \ - ( (FTC_Image_Cache)(lru)->user_data ) -#define FTC_QUEUE_LRU_GET_MANAGER( lru ) \ - FTC_QUEUE_LRU_GET_CACHE( lru )->manager -#define FTC_LRUNODE_QUEUE( node ) \ - ( (FTC_Image_Queue)(node)->root.data ) + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH IMAGE QUEUES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ LOCAL_FUNC_X - FT_Error ftc_image_cache_init_queue( FT_Lru lru, - FT_LruNode node ) + FT_Error ftc_image_queue_init( FTC_Image_Queue queue, + FTC_Image_Desc* type ) { - FTC_Image_Cache cache = FTC_QUEUE_LRU_GET_CACHE( lru ); - FTC_Image_Desc* desc = (FTC_Image_Desc*)node->key; - FT_Error error; - FTC_Image_Queue queue; - - - error = FTC_Image_Queue_New( cache, desc, &queue ); - if ( !error ) - { - /* good, now set the queue index within the queue object */ - queue->index = node - lru->nodes; - node->root.data = queue; - } - - return error; + queue->description = *type; + return 0; } LOCAL_FUNC_X - void ftc_image_cache_done_queue( FT_Lru lru, - FT_LruNode node ) + FT_Bool ftc_image_queue_compare( FTC_Image_Queue queue, + FTC_Image_Desc* type ) { - FTC_Image_Queue queue = FTC_LRUNODE_QUEUE( node ); - - FT_UNUSED( lru ); - - - FTC_Image_Queue_Done( queue ); + return !memcmp( &queue->description, type, sizeof(*type) ); } + - - LOCAL_FUNC_X - FT_Bool ftc_image_cache_compare_queue( FT_LruNode node, - FT_LruKey key ) + FT_CPLUSPLUS(const FTC_Glyph_Queue_Class) ftc_glyph_image_queue_class = { - FTC_Image_Queue queue = FTC_LRUNODE_QUEUE( node ); - FTC_Image_Desc* desc2 = (FTC_Image_Desc*)key; - FTC_Image_Desc* desc1 = &queue->descriptor; + sizeof( FTC_Image_QueueRec ), - - return ( desc1->size.face_id == desc2->size.face_id && - desc1->size.pix_width == desc2->size.pix_width && - desc1->size.pix_height == desc2->size.pix_height && - desc1->image_type == desc2->image_type ); - } - - - FT_CPLUSPLUS( const FT_Lru_Class ) ftc_image_queue_lru_class = - { - sizeof( FT_LruRec ), - ftc_image_cache_init_queue, - ftc_image_cache_done_queue, - 0, /* no flush */ - ftc_image_cache_compare_queue + (FTC_Glyph_Queue_InitFunc) ftc_image_queue_init, + (FTC_Glyph_Queue_DoneFunc) 0, + (FTC_Glyph_Queue_CompareFunc) ftc_image_queue_compare, + + (FTC_Glyph_Queue_NewNodeFunc) ftc_glyph_image_node_new, + (FTC_Glyph_Queue_SizeNodeFunc) ftc_glyph_image_node_size, + (FTC_Glyph_Queue_DestroyNodeFunc) ftc_glyph_image_node_destroy }; - /* compress image cache if necessary, i.e., discard all old glyph images */ - /* until `cache.num_bytes' is less than `cache.max_bytes'. Note that */ - /* this function will avoid to remove `new_node'. */ - static - void FTC_Image_Cache_Compress( FTC_Image_Cache cache, - FTC_ImageNode new_node ) - { - while ( cache->num_bytes > cache->max_bytes ) - { - FT_ListNode cur; - FTC_Image_Queue queue; - FT_UInt glyph_index; - FT_UInt hash_index; - FT_UInt queue_index; - FT_ULong size; - FTC_ImageNode inode; - + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH IMAGE CACHE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ - /* exit our loop if there isn't any glyph image left, or if */ - /* we reached the newly created node (which happens always at the */ - /* start of the list) */ - - cur = cache->glyphs_lru.tail; - inode = FTC_LISTNODE_TO_IMAGENODE( cur ); - if ( !cur || inode == new_node ) - break; - - glyph_index = FTC_IMAGENODE_GET_GINDEX( inode ); - queue_index = FTC_IMAGENODE_GET_QINDEX( inode ); - queue = (FTC_Image_Queue)cache->queues_lru-> - nodes[queue_index].root.data; - hash_index = glyph_index % queue->hash_size; - size = queue->clazz->size_image( queue, inode ) + - sizeof(FTC_ImageNodeRec); - - FT_List_Remove( &cache->glyphs_lru, cur ); - FT_List_Remove( queue->buckets + hash_index, (FT_ListNode)inode ); - queue->clazz->done_image( queue, inode ); - FTC_ImageNode_Done( cache, inode ); - - cache->num_bytes -= size; - } - } - FT_EXPORT_DEF( FT_Error ) FTC_Image_Cache_New( FTC_Manager manager, - FT_ULong max_bytes, - FTC_Image_Cache* acache ) + FT_CPLUSPLUS(const FTC_Glyph_Cache_Class) ftc_glyph_image_cache_class = { - FT_Error error; - FT_Memory memory; - FTC_Image_Cache cache; - - - if ( !manager ) - return FT_Err_Invalid_Cache_Handle; - - if ( !acache || !manager->library ) - return FT_Err_Invalid_Argument; - - *acache = 0; - memory = manager->library->memory; - - if ( ALLOC( cache, sizeof ( *cache ) ) ) - goto Exit; - - cache->manager = manager; - cache->memory = manager->library->memory; - cache->max_bytes = max_bytes; - - error = FT_Lru_New( &ftc_image_queue_lru_class, - FTC_MAX_IMAGE_QUEUES, - cache, - memory, - 1, /* pre_alloc == TRUE */ - &cache->queues_lru ); - if ( error ) - goto Exit; - - *acache = cache; - - Exit: - if ( error ) - FREE( cache ); - - return error; - } + { + sizeof( FTC_Glyph_CacheRec ), + (FTC_Cache_InitFunc) FTC_Glyph_Cache_Init, + (FTC_Cache_DoneFunc) FTC_Glyph_Cache_Done + }, + (FTC_Glyph_Queue_Class*) &ftc_glyph_image_queue_class + }; - FT_EXPORT_DEF( void ) FTC_Image_Cache_Done( FTC_Image_Cache cache ) + FT_EXPORT_FUNC( FT_Error ) FTC_Image_Cache_New( FTC_Manager manager, + FTC_Image_Cache* acache ) { - FT_Memory memory; - - - if ( !cache ) - return; - - memory = cache->memory; - - /* discard image queues */ - FT_Lru_Done( cache->queues_lru ); - - /* discard cache */ - FREE( cache ); + return FTC_Manager_Register_Cache( + manager, + (FTC_Cache_Class*)&ftc_glyph_image_cache_class, + (FTC_Cache*)acache ); } - + FT_EXPORT_DEF( FT_Error ) FTC_Image_Cache_Lookup( FTC_Image_Cache cache, @@ -553,43 +226,47 @@ FT_Glyph* aglyph ) { FT_Error error; - FTC_Image_Queue queue; - FTC_ImageNode inode; + FTC_Glyph_Queue queue; + FTC_GlyphNode inode; + FTC_Manager manager; + FTC_Image_Queue img_queue; /* check for valid `desc' delayed to FT_Lru_Lookup() */ if ( !cache || !aglyph ) return FT_Err_Invalid_Argument; - *aglyph = 0; - queue = cache->last_queue; - if ( !queue || - queue->descriptor.size.face_id != desc->size.face_id || - queue->descriptor.size.pix_width != desc->size.pix_width || - queue->descriptor.size.pix_height != desc->size.pix_height || - queue->descriptor.image_type != desc->image_type ) + *aglyph = 0; + queue = cache->root.last_queue; + img_queue = (FTC_Image_Queue)queue; + if ( !queue || memcmp( &img_queue->description, desc, sizeof(*desc) ) ) { - error = FT_Lru_Lookup( cache->queues_lru, + error = FT_Lru_Lookup( cache->root.queues_lru, (FT_LruKey)desc, (FT_Pointer*)&queue ); - cache->last_queue = queue; + cache->root.last_queue = queue; if ( error ) goto Exit; } - error = FTC_Image_Queue_Lookup_Node( queue, gindex, &inode ); + error = FTC_Glyph_Queue_Lookup_Node( queue, gindex, &inode ); if ( error ) goto Exit; - if (cache->num_bytes > cache->max_bytes) - FTC_Image_Cache_Compress( cache, inode ); + /* now compress the manager's cache pool if needed */ + manager = cache->root.root.manager; + if (manager->num_bytes > manager->max_bytes) + { + FTC_GlyphNode_Ref(inode); + FTC_Manager_Compress( manager ); + FTC_GlyphNode_Unref(inode); + } - *aglyph = FTC_IMAGENODE_GET_GLYPH( inode ); + *aglyph = FTC_GLYPHNODE_GET_GLYPH( inode ); Exit: return error; } -/* END */ diff --git a/src/cache/ftcimage.h b/src/cache/ftcimage.h index 558a7279..cf29d2a8 100644 --- a/src/cache/ftcimage.h +++ b/src/cache/ftcimage.h @@ -1,137 +1,21 @@ -/***************************************************************************/ -/* */ -/* ftcimage.h */ -/* */ -/* FreeType Image Cache (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - #ifndef FTCIMAGE_H #define FTCIMAGE_H -#include <cache/ftcmanag.h> -#include <freetype/ftglyph.h> -#include <stddef.h> - -#ifdef __cplusplus - extern "C" { -#endif - -#define FTC_MAX_IMAGE_QUEUES 16 +#include <freetype/cache/ftcglyph.h> - typedef struct FTC_Image_QueueRec_* FTC_Image_Queue; - typedef struct FTC_ImageNodeRec_* FTC_ImageNode; - - - /* macros used to pack a glyph index and a queue index in a single ptr */ -#define FTC_PTR_TO_GINDEX( p ) ( (FT_UInt)( (FT_ULong)(p) >> 16 ) ) -#define FTC_PTR_TO_QINDEX( p ) ( (FT_UInt)( (FT_ULong)(p) & 0xFFFF ) ) -#define FTC_INDICES_TO_PTR( g, q ) \ - ( (FT_Pointer)( ( (FT_ULong)(g) << 16 ) | \ - ( (FT_ULong)(q) & 0xFFFF) ) ) - - typedef struct FTC_ImageNodeRec_ + /* the glyph image queue type */ + typedef struct FTC_Image_QueueRec_ { - /* root1.data contains an FT_Glyph handle */ - FT_ListNodeRec root1; - - /* root2.data contains a glyph index + queue index */ - FT_ListNodeRec root2; - - } FTC_ImageNodeRec; - - - /* macros to read/set the glyph & queue index in a FTC_ImageNode */ -#define FTC_IMAGENODE_GET_GINDEX( n ) FTC_PTR_TO_GINDEX( (n)->root2.data ) -#define FTC_IMAGENODE_GET_QINDEX( n ) FTC_PTR_TO_QINDEX( (n)->root2.data ) -#define FTC_IMAGENODE_GET_GLYPH( n ) ( (FT_Glyph)(n)->root1.data ) -#define FTC_IMAGENODE_SET_GLYPH( n, g ) \ - do \ - { \ - (n)->root1.data = g; \ - } while ( 0 ) - -#define FTC_IMAGENODE_SET_INDICES( n, g, q ) \ - do \ - { \ - (n)->root2.data = FTC_INDICES_TO_PTR( g, q ); \ - } while ( 0 ) - - - /* this macro is used to extract a handle to the global LRU list node */ - /* corresponding to a given image node */ -#define FTC_IMAGENODE_TO_LISTNODE( n ) \ - ( (FT_ListNode)&(n)->root2 ) - - /* this macro is used to extract a handle to a given image node from */ - /* the corresponding LRU glyph list node. That's a bit hackish.. */ -#define FTC_LISTNODE_TO_IMAGENODE( p ) \ - ( (FTC_ImageNode)( (char*)(p) - \ - offsetof( FTC_ImageNodeRec,root2 ) ) ) - + FTC_Glyph_QueueRec root; + FTC_Image_Desc description; + + } FTC_Image_QueueRec, *FTC_Image_Queue; - typedef struct FTC_Image_CacheRec_ + typedef struct FTC_Image_CacheRec_ { - FTC_Manager manager; - FT_Memory memory; - - FT_ULong max_bytes; /* maximum size of cache in bytes */ - FT_ULong num_bytes; /* current size of cache in bytes */ + FTC_Glyph_CacheRec root; - FT_Lru queues_lru; /* static queues lru list */ - FT_ListRec glyphs_lru; /* global lru list of glyph images */ - - FTC_Image_Queue last_queue; /* small cache */ - } FTC_Image_CacheRec; - - /* a table of functions used to generate/manager glyph images */ - typedef struct FTC_Image_Class_ - { - FT_Error (*init_image)( FTC_Image_Queue queue, - FTC_ImageNode node ); - - void (*done_image)( FTC_Image_Queue queue, - FTC_ImageNode node ); - - FT_ULong (*size_image)( FTC_Image_Queue queue, - FTC_ImageNode node ); - - } FTC_Image_Class; - - - typedef struct FTC_Image_QueueRec_ - { - FTC_Image_Cache cache; - FTC_Manager manager; - FT_Memory memory; - FTC_Image_Class* clazz; - FTC_Image_Desc descriptor; - FT_UInt hash_size; - FT_List buckets; - FT_UInt index; /* index in parent cache */ - - } FTC_Image_QueueRec; - - - -#ifdef __cplusplus - } -#endif - - #endif /* FTCIMAGE_H */ - -/* END */ diff --git a/src/cache/ftcmanag.c b/src/cache/ftcmanag.c index a30579fc..97630d1c 100644 --- a/src/cache/ftcmanag.c +++ b/src/cache/ftcmanag.c @@ -16,9 +16,13 @@ /***************************************************************************/ -#include <cache/ftcmanag.h> +#include <freetype/cache/ftcmanag.h> #include <freetype/internal/ftobjs.h> +#include <freetype/internal/ftdebug.h> +#include <freetype/ftlist.h> +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache #define FTC_LRU_GET_MANAGER( lru ) (FTC_Manager)lru->user_data @@ -38,6 +42,7 @@ { FTC_Manager manager = FTC_LRU_GET_MANAGER( lru ); FT_Error error; + FT_Face face; error = manager->request_face( (FTC_FaceID)node->key, @@ -47,9 +52,7 @@ if ( !error ) { /* destroy initial size object; it will be re-created later */ - FT_Face face = (FT_Face)node->root.data; - - + face = (FT_Face)node->root.data; FT_Done_Size( face->size ); } @@ -89,23 +92,23 @@ } - typedef struct FTC_SizeRequest_ + typedef struct FTC_FontRequest_ { FT_Face face; FT_UShort width; FT_UShort height; - } FTC_SizeRequest; + } FTC_FontRequest; LOCAL_FUNC_X FT_Error ftc_manager_init_size( FT_Lru lru, FT_LruNode node ) { - FTC_SizeRequest* size_req = (FTC_SizeRequest*)node->key; + FTC_FontRequest* font_req = (FTC_FontRequest*)node->key; FT_Size size; FT_Error error; - FT_Face face = size_req->face; + FT_Face face = font_req->face; FT_UNUSED( lru ); @@ -116,8 +119,8 @@ { face->size = size; error = FT_Set_Pixel_Sizes( face, - size_req->width, - size_req->height ); + font_req->width, + font_req->height ); if ( error ) FT_Done_Size( size ); else @@ -142,7 +145,7 @@ FT_LruNode node, FT_LruKey key ) { - FTC_SizeRequest* req = (FTC_SizeRequest*)key; + FTC_FontRequest* req = (FTC_FontRequest*)key; FT_Size size = (FT_Size)node->root.data; FT_Error error; @@ -168,7 +171,7 @@ FT_Bool ftc_manager_compare_size( FT_LruNode node, FT_LruKey key ) { - FTC_SizeRequest* req = (FTC_SizeRequest*)key; + FTC_FontRequest* req = (FTC_FontRequest*)key; FT_Size size = (FT_Size)node->root.data; FT_UNUSED( node ); @@ -203,6 +206,7 @@ FT_EXPORT_FUNC( FT_Error ) FTC_Manager_New( FT_Library library, FT_UInt max_faces, FT_UInt max_sizes, + FT_ULong max_bytes, FTC_Face_Requester requester, FT_Pointer req_data, FTC_Manager* amanager ) @@ -221,10 +225,13 @@ goto Exit; if ( max_faces == 0 ) - max_faces = FTC_MAX_FACES; + max_faces = FTC_MAX_FACES_DEFAULT; if ( max_sizes == 0 ) - max_sizes = FTC_MAX_SIZES; + max_sizes = FTC_MAX_SIZES_DEFAULT; + + if ( max_bytes == 0 ) + max_bytes = FTC_MAX_BYTES_DEFAULT; error = FT_Lru_New( &ftc_face_lru_class, max_faces, @@ -245,6 +252,7 @@ goto Exit; manager->library = library; + manager->max_bytes = max_bytes; manager->request_face = requester; manager->request_data = req_data; *amanager = manager; @@ -264,6 +272,7 @@ FT_EXPORT_DEF( void ) FTC_Manager_Done( FTC_Manager manager ) { FT_Memory memory; + FT_UInt index; if ( !manager || !manager->library ) @@ -271,19 +280,35 @@ memory = manager->library->memory; + /* now discard all caches */ + for (index = 0; index < FTC_MAX_CACHES; index++ ) + { + FTC_Cache cache = manager->caches[index]; + + + if (cache) + { + cache->clazz->done_cache( cache ); + FREE(cache); + manager->caches[index] = 0; + } + } + + /* discard faces and sizes */ FT_Lru_Done( manager->sizes_lru ); FT_Lru_Done( manager->faces_lru ); + FREE( manager ); } FT_EXPORT_DEF( void ) FTC_Manager_Reset( FTC_Manager manager ) { - if ( !manager ) - return; - - FT_Lru_Reset( manager->sizes_lru ); - FT_Lru_Reset( manager->faces_lru ); + if (manager ) + { + FT_Lru_Reset( manager->sizes_lru ); + FT_Lru_Reset( manager->faces_lru ); + } } @@ -298,14 +323,14 @@ (FT_LruKey)face_id, (FT_Pointer*)aface ); } - - + + FT_EXPORT_DEF( FT_Error ) FTC_Manager_Lookup_Size( FTC_Manager manager, - FTC_SizeID size_id, + FTC_Font font, FT_Face* aface, FT_Size* asize ) { - FTC_SizeRequest req; + FTC_FontRequest req; FT_Error error; FT_Face face; @@ -318,15 +343,15 @@ if ( asize ) *asize = 0; - error = FTC_Manager_Lookup_Face( manager, size_id->face_id, &face ); + error = FTC_Manager_Lookup_Face( manager, font->face_id, &face ); if ( !error ) { FT_Size size; req.face = face; - req.width = size_id->pix_width; - req.height = size_id->pix_height; + req.width = font->pix_width; + req.height = font->pix_height; error = FT_Lru_Lookup( manager->sizes_lru, (FT_LruKey)&req, @@ -348,4 +373,98 @@ } + /* "compress" the manager's data, i.e. get rids of old cache nodes */ + /* that are not referenced anymore in order to limit the total */ + /* memory used by the cache.. */ + FT_EXPORT_FUNC(void) FTC_Manager_Compress( FTC_Manager manager ) + { + FT_ListNode node; + + node = manager->global_lru.tail; + while (manager->num_bytes > manager->max_bytes && node) + { + FTC_CacheNode cache_node = FTC_LIST_TO_CACHENODE(node); + FTC_CacheNode_Data* data = FTC_CACHENODE_TO_DATA_P(cache_node); + FTC_Cache cache; + FT_ListNode prev = node->prev; + + if (data->ref_count <= 0) + { + /* ok, we're going to remove this node */ + FT_List_Remove( &manager->global_lru, node ); + + /* finalize cache node */ + cache = manager->caches[data->cache_index]; + if (cache) + { + FTC_CacheNode_Class* clazz = cache->node_clazz; + + manager->num_bytes -= clazz->size_node( cache_node, + cache->cache_user ); + + clazz->destroy_node( cache_node, cache->cache_user ); + } + else + { + /* this should never happen !! */ + FT_ERROR(( "FTC_Manager_Compress: Cache Manager is corrupted !!\n" )); + } + } + node = prev; + } + } + + + FT_EXPORT_DEF( FT_Error ) FTC_Manager_Register_Cache( + FTC_Manager manager, + FTC_Cache_Class* clazz, + FTC_Cache *acache ) + { + FT_Error error = FT_Err_Invalid_Argument; + + + if ( manager && clazz && acache ) + { + FT_Memory memory = manager->library->memory; + FTC_Cache cache; + FT_UInt index = 0; + + /* by default, return 0 */ + *acache = 0; + + /* check for an empty cache slot in the manager's table */ + for ( index = 0; index < FTC_MAX_CACHES; index++ ) + { + if ( manager->caches[index] == 0 ) + break; + } + + /* return an error if there are too many registered caches */ + if (index >= FTC_MAX_CACHES) + { + error = FT_Err_Too_Many_Caches; + FT_ERROR(( "FTC_Manager_Register_Cache:" )); + FT_ERROR(( " too many registered caches..\n" )); + goto Exit; + } + + if ( !ALLOC( cache, clazz->cache_byte_size ) ) + { + cache->manager = manager; + cache->memory = memory; + cache->clazz = clazz; + + if (clazz->init_cache) + error = clazz->init_cache( cache ); + + if (error) + FREE(cache); + else + manager->caches[index] = *acache = cache; + } + } + Exit: + return error; + } + /* END */ diff --git a/src/cache/ftlru.c b/src/cache/ftlru.c index 288dd411..4b912993 100644 --- a/src/cache/ftlru.c +++ b/src/cache/ftlru.c @@ -16,7 +16,7 @@ /***************************************************************************/ -#include <cache/ftlru.h> +#include <freetype/cache/ftlru.h> #include <freetype/internal/ftobjs.h> #include <freetype/internal/ftlist.h> diff --git a/src/cache/rules.mk b/src/cache/rules.mk index a6b6801c..8cdf1f6e 100644 --- a/src/cache/rules.mk +++ b/src/cache/rules.mk @@ -15,9 +15,11 @@ # Cache driver directory # -Cache_DIR := $(SRC_)cache -Cache_DIR_ := $(Cache_DIR)$(SEP) +CACHE_DIR := $(SRC_)cache +CACHE_DIR_ := $(CACHE_DIR)$(SEP) +CACHE_H_DIR := $(PUBLIC_)cache +CACHE_H_DIR_ := $(CACHE_H_DIR)$(SEP) # compilation flags for the driver # @@ -26,13 +28,17 @@ Cache_COMPILE := $(FT_COMPILE) # Cache driver sources (i.e., C files) # -Cache_DRV_SRC := $(Cache_DIR_)ftlru.c \ - $(Cache_DIR_)ftcmanag.c \ - $(Cache_DIR_)ftcimage.c +Cache_DRV_SRC := $(CACHE_DIR_)ftlru.c \ + $(CACHE_DIR_)ftcmanag.c \ + $(CACHE_DIR_)ftcglyph.c \ + $(CACHE_DIR_)ftcimage.c # Cache driver headers # -Cache_DRV_H := $(Cache_DRV_SRC:%c=%h) +Cache_DRV_H := $(CACHE_H_DIR_)ftlru.h \ + $(CACHE_H_DIR_)ftcmanag.h \ + $(CACHE_H_DIR_)ftcglyph.h \ + $(CACHE_DIR_)ftcimage.h # Cache driver object(s) @@ -40,12 +46,12 @@ Cache_DRV_H := $(Cache_DRV_SRC:%c=%h) # Cache_DRV_OBJ_M is used during `multi' builds. # Cache_DRV_OBJ_S is used during `single' builds. # -Cache_DRV_OBJ_M := $(Cache_DRV_SRC:$(Cache_DIR_)%.c=$(OBJ_)%.$O) +Cache_DRV_OBJ_M := $(Cache_DRV_SRC:$(CACHE_DIR_)%.c=$(OBJ_)%.$O) Cache_DRV_OBJ_S := $(OBJ_)ftcache.$O # Cache driver source file for single build # -Cache_DRV_SRC_S := $(Cache_DIR_)ftcache.c +Cache_DRV_SRC_S := $(CACHE_DIR_)ftcache.c # Cache driver - single object @@ -57,7 +63,7 @@ $(Cache_DRV_OBJ_S): $(Cache_DRV_SRC_S) $(Cache_DRV_SRC) \ # Cache driver - multiple objects # -$(OBJ_)%.$O: $(Cache_DIR_)%.c $(FREETYPE_H) $(Cache_DRV_H) +$(OBJ_)%.$O: $(CACHE_DIR_)%.c $(FREETYPE_H) $(Cache_DRV_H) $(Cache_COMPILE) $T$@ $< |