Commit 6b4a4610 authored by David Turner's avatar David Turner
Browse files

- completed the abstract chunk cache class

- started implementin a "small-bitmaps" cache derived from it
- (soon a "metrics" cache will be written too)
parent 843997b2
/***************************************************************************/
/* */
/* ftcchunk.h */
/* */
/* FreeType chunk 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. */
/* */
/***************************************************************************/
/*************************************************************************/
/* */
/* Important: The functions defined in this file are only used to */
/* implement an abstract chunk cache class. You need to */
/* provide additional logic to implement a complete cache. */
/* For example, see `ftcmetrx.h' and `ftcmetrx.c' which */
/* implement a glyph metrics cache based on this code. */
/* */
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/********* *********/
/********* WARNING, THIS IS ALPHA CODE, THIS API *********/
/********* IS DUE TO CHANGE UNTIL STRICTLY NOTIFIED BY THE *********/
/********* FREETYPE DEVELOPMENT TEAM *********/
/********* *********/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
#ifndef FTCCHUNK_H
#define FTCCHUNK_H
#include <freetype/cache/ftcmanag.h>
#ifdef __cplusplus
extern "C" {
#endif
/* maximum number of chunk sets in a given chunk cache */
#define FTC_MAX_CHUNK_SETS 16
typedef struct FTC_ChunkRec_* FTC_Chunk;
typedef struct FTC_ChunkSetRec_* FTC_ChunkSet;
typedef struct FTC_Chunk_CacheRec_* FTC_Chunk_Cache;
typedef struct FTC_ChunkRec_
{
FTC_CacheNodeRec root;
FTC_ChunkSet cset;
FT_UShort cset_index;
FT_UShort num_elements;
FT_Byte* elements;
} FTC_ChunkRec;
/*************************************************************************/
/* */
/* chunk set methods */
/* */
typedef FT_Error (*FTC_ChunkSet_InitFunc) ( FTC_ChunkSet cset,
FT_Pointer type );
typedef void (*FTC_ChunkSet_DoneFunc) ( FTC_ChunkSet cset );
typedef FT_Bool (*FTC_ChunkSet_CompareFunc)( FTC_ChunkSet cset,
FT_Pointer type );
typedef FT_Error (*FTC_ChunkSet_NewNodeFunc)( FTC_ChunkSet cset,
FT_UInt index,
FTC_ChunkNode* anode );
typedef void (*FTC_ChunkSet_DestroyNodeFunc)( FTC_ChunkNode node );
typedef FT_ULong (*FTC_ChunkSet_SizeNodeFunc) ( FTC_ChunkNode node );
typedef struct FTC_ChunkSet_Class_
{
FT_UInt cset_size;
FTC_ChunkSet_InitFunc init;
FTC_ChunkSet_DoneFunc done;
FTC_ChunkSet_CompareFunc compare;
FTC_ChunkSet_NewNodeFunc new_node;
FTC_ChunkSet_SizeNodeFunc size_node;
FTC_ChunkSet_DestroyNodeFunc destroy_node;
} FTC_ChunkSet_Class;
typedef struct FTC_ChunkSetRec_
{
FTC_Chunk_Cache cache;
FTC_Manager manager;
FT_Memory memory;
FTC_ChunkSet_Class* clazz;
FT_UInt cset_index; /* index in parent cache */
FT_UInt element_max; /* maximum number of elements */
FT_UInt element_size; /* element size in bytes */
FT_UInt element_count; /* number of elements per chunk */
FT_UInt num_chunks;
FTC_ChunkNode* chunks;
} FTC_ChunkSetRec;
/* the abstract chunk cache class */
typedef struct FTC_Chunk_Cache_Class_
{
FTC_Cache_Class root;
FTC_ChunkSet_Class* cset_class;
} FTC_Chunk_Cache_Class;
/* the abstract chunk cache object */
typedef struct FTC_Chunk_CacheRec_
{
FTC_CacheRec root;
FT_Lru csets_lru; /* static chunk set lru list */
FTC_ChunkSet last_cset; /* small cache :-) */
} FTC_Chunk_CacheRec;
/*************************************************************************/
/* */
/* These functions are exported so that they can be called from */
/* user-provided cache classes; otherwise, they are really parts of the */
/* cache sub-system internals. */
/* */
FT_EXPORT_FUNC( NV_Error )
FTC_ChunkNode_Init( FTC_ChunkNode node,
FTC_ChunkSet cset,
FT_UInt index,
FT_Bool alloc );
#define FTC_ChunkNode_Ref( n ) \
FTC_CACHENODE_TO_DATA_P( &(n)->root )->ref_count++
#define FTC_ChunkNode_Unref( n ) \
FTC_CACHENODE_TO_DATA_P( &(n)->root )->ref_count--
FT_EXPORT_DEF( void )
FTC_ChunkNode_Destroy( FTC_ChunkNode node );
FT_EXPORT_DEF( FT_Error )
FTC_Chunk_Cache_Init( FTC_Chunk_Cache cache );
FT_EXPORT_DEF( void )
FTC_Chunk_Cache_Done( FTC_Chunk_Cache cache );
FT_EXPORT_DEF( FT_Error )
FTC_ChunkSet_New( FTC_Chunk_Cache cache,
FT_Pointer type,
FT_UInt num_elements,
FT_UInt element_size,
FT_UInt chunk_size,
FTC_ChunkSet *aset )
FT_EXPORT_DEF( FT_Error )
FTC_ChunkSet_Lookup_Node( FTC_ChunkSet cset,
FT_UInt glyph_index,
FTC_ChunkNode *anode,
FT_UInt *aindex );
#ifdef __cplusplus
}
#endif
#endif /* FTCCHUNK_H */
/* END */
......@@ -57,21 +57,20 @@
#endif
/* maximum number of queues per glyph cache; must be < 256 */
#define FTC_MAX_GLYPH_QUEUES 16
/* maximum number of glyph sets per glyph cache; must be < 256 */
#define FTC_MAX_GLYPH_SETS 16
#define FTC_GSET_HASH_SIZE_DEFAULT 64
#define FTC_QUEUE_HASH_SIZE_DEFAULT 64
typedef struct FTC_Glyph_QueueRec_* FTC_Glyph_Queue;
typedef struct FTC_GlyphSetRec_* FTC_GlyphSet;
typedef struct FTC_GlyphNodeRec_* FTC_GlyphNode;
typedef struct FTC_Glyph_CacheRec_* FTC_Glyph_Cache;
typedef struct FTC_GlyphNodeRec_
typedef struct FTC_GlyphNodeRec_
{
FTC_CacheNodeRec root;
FTC_GlyphNode queue_next; /* next in queue's bucket list */
FTC_GlyphNode gset_next; /* next in glyph set's bucket list */
FT_UShort glyph_index;
FT_UShort queue_index;
FT_UShort gset_index;
} FTC_GlyphNodeRec;
......@@ -83,62 +82,62 @@
/*************************************************************************/
/* */
/* Glyph queue methods. */
/* Glyph set methods. */
/* */
typedef FT_Error (*FTC_Glyph_Queue_InitFunc)( FTC_Glyph_Queue queue,
FT_Pointer type );
typedef FT_Error (*FTC_GlyphSet_InitFunc) ( FTC_GlyphSet gset,
FT_Pointer type );
typedef void (*FTC_GlyphSet_DoneFunc) ( FTC_GlyphSet gset );
typedef void (*FTC_Glyph_Queue_DoneFunc)( FTC_Glyph_Queue queue );
typedef FT_Bool (*FTC_GlyphSet_CompareFunc)( FTC_GlyphSet gset,
FT_Pointer type );
typedef FT_Bool (*FTC_Glyph_Queue_CompareFunc)( FTC_Glyph_Queue queue,
FT_Pointer type );
typedef FT_Error (*FTC_Glyph_Queue_NewNodeFunc)( FTC_Glyph_Queue queue,
FT_UInt gindex,
FTC_GlyphNode* anode );
typedef FT_Error (*FTC_GlyphSet_NewNodeFunc)( FTC_GlyphSet gset,
FT_UInt gindex,
FTC_GlyphNode *anode );
typedef void (*FTC_Glyph_Queue_DestroyNodeFunc)( FTC_GlyphNode node,
FTC_Glyph_Queue queue );
typedef void (*FTC_GlyphSet_DestroyNodeFunc)( FTC_GlyphNode node,
FTC_GlyphSet gset );
typedef FT_ULong (*FTC_Glyph_Queue_SizeNodeFunc)( FTC_GlyphNode node,
FTC_Glyph_Queue queue );
typedef FT_ULong (*FTC_GlyphSet_SizeNodeFunc)( FTC_GlyphNode node,
FTC_GlyphSet gset );
typedef struct FTC_Glyph_Queue_Class_
typedef struct FTC_GlyphSet_Class_
{
FT_UInt queue_byte_size;
FT_UInt gset_byte_size;
FTC_Glyph_Queue_InitFunc init;
FTC_Glyph_Queue_DoneFunc done;
FTC_Glyph_Queue_CompareFunc compare;
FTC_GlyphSet_InitFunc init;
FTC_GlyphSet_DoneFunc done;
FTC_GlyphSet_CompareFunc compare;
FTC_Glyph_Queue_NewNodeFunc new_node;
FTC_Glyph_Queue_SizeNodeFunc size_node;
FTC_Glyph_Queue_DestroyNodeFunc destroy_node;
FTC_GlyphSet_NewNodeFunc new_node;
FTC_GlyphSet_SizeNodeFunc size_node;
FTC_GlyphSet_DestroyNodeFunc destroy_node;
} FTC_Glyph_Queue_Class;
} FTC_GlyphSet_Class;
typedef struct FTC_Glyph_QueueRec_
typedef struct FTC_GlyphSetRec_
{
FTC_Glyph_Cache cache;
FTC_Manager manager;
FT_Memory memory;
FTC_Glyph_Queue_Class* clazz;
FTC_Image_Desc descriptor;
FT_UInt hash_size;
FTC_GlyphNode* buckets;
FT_UInt queue_index; /* index in parent cache */
FTC_Glyph_Cache cache;
FTC_Manager manager;
FT_Memory memory;
FTC_GlyphSet_Class* clazz;
FT_UInt hash_size;
FTC_GlyphNode* buckets;
FT_UInt gset_index; /* index in parent cache */
} FTC_Glyph_QueueRec;
} FTC_GlyphSetRec;
/* the abstract glyph cache class */
typedef struct FTC_Glyph_Cache_Class_
{
FTC_Cache_Class root;
FTC_Glyph_Queue_Class* queue_class;
FTC_Cache_Class root;
FTC_GlyphSet_Class* gset_class;
} FTC_Glyph_Cache_Class;
......@@ -146,9 +145,9 @@
/* the abstract glyph cache object */
typedef struct FTC_Glyph_CacheRec_
{
FTC_CacheRec root;
FT_Lru queues_lru; /* static queues lru list */
FTC_Glyph_Queue last_queue; /* small cache :-) */
FTC_CacheRec root;
FT_Lru gsets_lru; /* static sets lru list */
FTC_GlyphSet last_gset; /* small cache :-) */
} FTC_Glyph_CacheRec;
......@@ -161,9 +160,9 @@
/* */
FT_EXPORT_FUNC( void )
FTC_GlyphNode_Init( FTC_GlyphNode node,
FTC_Glyph_Queue queue,
FT_UInt gindex );
FTC_GlyphNode_Init( FTC_GlyphNode node,
FTC_GlyphSet gset,
FT_UInt gindex );
#define FTC_GlyphNode_Ref( n ) \
FTC_CACHENODE_TO_DATA_P( &(n)->root )->ref_count++
......@@ -173,8 +172,8 @@
FT_EXPORT_DEF( void )
FTC_Destroy_Glyph_Node( FTC_GlyphNode node,
FTC_Glyph_Cache cache );
FTC_GlyphNode_Destroy( FTC_GlyphNode node,
FTC_Glyph_Cache cache );
......@@ -189,15 +188,15 @@
FT_EXPORT_DEF( FT_Error )
FTC_Glyph_Queue_New( FTC_Glyph_Cache cache,
FT_Pointer type,
FTC_Glyph_Queue* aqueue );
FTC_GlyphSet_New( FTC_Glyph_Cache cache,
FT_Pointer type,
FTC_GlyphSet *aset );
FT_EXPORT_DEF( FT_Error )
FTC_Glyph_Queue_Lookup_Node( FTC_Glyph_Queue queue,
FT_UInt glyph_index,
FTC_GlyphNode* anode );
FTC_GlyphSet_Lookup_Node( FTC_GlyphSet gset,
FT_UInt glyph_index,
FTC_GlyphNode *anode );
#ifdef __cplusplus
......@@ -205,6 +204,6 @@
#endif
#endif /* FTCIMAGE_H */
#endif /* FTCGLYPH_H */
/* END */
......@@ -450,7 +450,7 @@
/* failure. */
/* */
/* <Return> */
/* FreType error code. 0 means success. */
/* error code, 0 means success */
/* */
/* <Note> */
/* the returned glyph is owned and manager by the glyph image cache. */
......@@ -461,11 +461,11 @@
/* taken by the glyphs it holds, the returned glyph might disappear */
/* on a later invocation of this function! It's a cache after all... */
/* */
FT_EXPORT_DEF( FT_Error ) FTC_Image_Cache_Lookup(
FTC_Image_Cache cache,
FTC_Image_Desc* desc,
FT_UInt gindex,
FT_Glyph* aglyph );
FT_EXPORT_DEF( FT_Error )
FTC_Image_Cache_Lookup( FTC_Image_Cache cache,
FTC_Image_Desc* desc,
FT_UInt gindex,
FT_Glyph* aglyph );
#ifdef __cplusplus
......
/***************************************************************************/
/* */
/* ftcchunk.c */
/* */
/* FreeType chunk cache 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 <freetype/cache/ftcglyph.h>
#include <freetype/fterrors.h>
#include <freetype/internal/ftobjs.h>
#include <freetype/internal/ftlist.h>
#include <freetype/fterrors.h>
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GLYPH NODES *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* create a new chunk node, setting its cache index and ref count */
FT_EXPORT_FUNC( NV_Error )
FTC_ChunkNode_Init( FTC_ChunkNode node,
FTC_ChunkSet cset,
FT_UInt index,
FT_Bool alloc )
{
FTC_Chunk_Cache cache = cset->cache;
FTC_CacheNode_Data* data = FTC_CACHENODE_TO_DATA_P( &node->root );
NV_Error error = 0;
data->cache_index = (FT_UShort) cache->root.cache_index;
data->ref_count = (FT_Short) 0;
node->cset_index = (FT_UShort) index;
node->num_elements = (index+1 < cset->chunk_count)
? cset->chunk_size
: cset->element_max - cset->chunk_count*index;
if (alloc)
{
/* allocate elements array */
memory = cache->root.memory;
error = MEM_ALLOC( cache->elements, cset->element_size *
cset->element_count );
}
return error;
}
FT_EXPORT_FUNC( void ) FTC_ChunkNode_Destroy( FTC_ChunkNode node )
{
FTC_ChunkSet cset = node->cset;
/* remove from parent set table */
cset->chunks[ node->cset_index ] = 0;
/* destroy the node */
cset->clazz->destroy_node( node );
}
FT_EXPORT_FUNC( FT_ULong ) FTC_ChunkNode_Size( FTC_ChunkNode node )
{
FTC_ChunkSet cset = node->cset;
return cset->clazz->size_node( node, cset );
}
FT_CPLUSPLUS( const FTC_CacheNode_Class ) ftc_chunk_cache_node_class =
{
(FTC_CacheNode_SizeFunc) FTC_ChunkNode_Size,
(FTC_CacheNode_DestroyFunc) FTC_ChunkNode_Destroy
};
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** CHUNK SETS *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_EXPORT_FUNC( FT_Error )
FTC_ChunkSet_New( FTC_Chunk_Cache cache,
FT_Pointer type,
FT_UInt num_elements,
FT_UInt element_size,
FT_UInt chunk_size,
FTC_ChunkSet *aset )
{
FT_Error error;
FT_Memory memory = cache->root.memory;
FTC_Manager manager = cache->root.manager;
FTC_ChunkSet cset = 0;
FTC_Chunk_Cache_Class* ccache_class;
FTC_ChunkSet_Class* clazz;
ccache_class = (FTC_Chunk_Cache_Class*)cache->root.clazz;
clazz = ccache_class->cset_class;
*aset = 0;
if ( ALLOC( set, clazz->cset_byte_size ) )
goto Exit;
cset->cache = cache;
cset->manager = manager;
cset->memory = memory;
cset->element_max = num_elements;
cset->element_size = element_size;
cset->element_count = chunk_size;
cset->clazz = clazz;
/* compute maximum number of nodes */
cset->num_chunks = (num_elements + (chunk_size-1))/chunk_size;
/* allocate chunk pointers table */
if ( ALLOC_ARRAY( cset->chunks, cset->num_chunks, FTC_ChunkNode ) )
goto Exit;
/* initialize set by type if needed */
if ( clazz->init )
{
error = clazz->init( cset, type );
if ( error )
goto Exit;
}
*aset = cset;
Exit:
if ( error && cset )
{
FREE( cset->chunks );
FREE( cset );
}
return error;
}
FT_EXPORT_FUNC( void ) FTC_ChunkSet_Destroy( FTC_ChunkSet cset )
{
FTC_Chunk_Cache cache = cset->cache;
FTC_Manager manager = cache->root.manager;
FT_List glyphs_lru = &manager->global_lru;
FTC_ChunkNode* bucket = cset->chunk;
FTC_ChunkNode* bucket_limit = bucket + cset->num_chunks;
FT_Memory memory = cache->root.memory;
FTC_ChunkSet_Class* clazz = cset->clazz;
/* for each bucket, free the list of glyph nodes */
for ( ; bucket < bucket_limit; bucket++ )
{
FTC_ChunkNode node = bucket[0];
FT_ListNode lrunode;
lrunode = FTC_CHUNKNODE_TO_LRUNODE( node );
manager->num_bytes -= clazz->size_node( node );
FT_List_Remove( glyphs_lru, lrunode );
clazz->destroy_node( node );
bucket[0] = 0;
}
if ( clazz->done )
clazz->done( cset );
FREE( cset->chunks );
FREE( cset );
}
FT_EXPORT_FUNC( FT_Error )