From 7d0f1137dbee388f5d49b37231bd7c56e5d42e20 Mon Sep 17 00:00:00 2001 From: David Turner Date: Sat, 28 Oct 2000 23:34:45 +0000 Subject: [PATCH] completed the sbit cache, though it's still buggy :-( major reformatting of the cache subsystem (again) added substantial documentation too in header files --- include/freetype/cache/ftcchunk.h | 28 +- include/freetype/cache/ftcglyph.h | 12 +- include/freetype/cache/ftcimage.h | 190 ++++++++++++++ include/freetype/cache/ftcmanag.h | 175 ++++++++++-- {src => include/freetype}/cache/ftcsbits.h | 36 +-- include/freetype/cache/ftlru.h | 20 +- include/freetype/ftcache.h | 154 +---------- src/cache/ftcache.c | 4 + src/cache/ftcchunk.c | 64 +++-- src/cache/ftcglyph.c | 14 +- src/cache/ftcimage.c | 35 ++- src/cache/ftcimage.h | 160 +++++++++-- src/cache/ftcmanag.c | 16 +- src/cache/ftcsbits.c | 292 ++++++++++++--------- 14 files changed, 798 insertions(+), 402 deletions(-) create mode 100644 include/freetype/cache/ftcimage.h rename {src => include/freetype}/cache/ftcsbits.h (81%) diff --git a/include/freetype/cache/ftcchunk.h b/include/freetype/cache/ftcchunk.h index a36772c95..c2ee555df 100644 --- a/include/freetype/cache/ftcchunk.h +++ b/include/freetype/cache/ftcchunk.h @@ -58,11 +58,11 @@ #define FTC_MAX_CHUNK_SETS 16 - typedef struct FTC_ChunkRec_* FTC_Chunk; + typedef struct FTC_ChunkNodeRec_* FTC_ChunkNode; typedef struct FTC_ChunkSetRec_* FTC_ChunkSet; typedef struct FTC_Chunk_CacheRec_* FTC_Chunk_Cache; - typedef struct FTC_ChunkRec_ + typedef struct FTC_ChunkNodeRec_ { FTC_CacheNodeRec root; FTC_ChunkSet cset; @@ -70,14 +70,21 @@ FT_UShort num_elements; FT_Byte* elements; - } FTC_ChunkRec; + } FTC_ChunkNodeRec; +#define FTC_CHUNKNODE_TO_LRUNODE(x) ((FT_ListNode)(x)) +#define FTC_LRUNODE_TO_CHUNKNODE(x) ((FTC_ChunkNode)(x)) /*************************************************************************/ /* */ /* chunk set methods */ /* */ + /* used to set "element_max", "element_count" and "element_size" */ + typedef FT_Error (*FTC_ChunkSet_SizesFunc) ( FTC_ChunkSet cset, + FT_Pointer type ); + + typedef FT_Error (*FTC_ChunkSet_InitFunc) ( FTC_ChunkSet cset, FT_Pointer type ); @@ -100,11 +107,12 @@ typedef struct FTC_ChunkSet_Class_ { - FT_UInt cset_size; + FT_UInt cset_byte_size; FTC_ChunkSet_InitFunc init; FTC_ChunkSet_DoneFunc done; FTC_ChunkSet_CompareFunc compare; + FTC_ChunkSet_SizesFunc sizes; FTC_ChunkSet_NewNodeFunc new_node; FTC_ChunkSet_SizeNodeFunc size_node; @@ -119,11 +127,12 @@ FTC_Manager manager; FT_Memory memory; FTC_ChunkSet_Class* clazz; - FT_UInt cset_index; /* index in parent cache */ + 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; @@ -145,7 +154,7 @@ FTC_CacheRec root; FT_Lru csets_lru; /* static chunk set lru list */ FTC_ChunkSet last_cset; /* small cache :-) */ - + } FTC_Chunk_CacheRec; /*************************************************************************/ @@ -155,7 +164,7 @@ /* cache sub-system internals. */ /* */ - FT_EXPORT_FUNC( NV_Error ) + FT_EXPORT_FUNC( FT_Error ) FTC_ChunkNode_Init( FTC_ChunkNode node, FTC_ChunkSet cset, FT_UInt index, @@ -186,10 +195,7 @@ 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 ) + FTC_ChunkSet *aset ); FT_EXPORT_DEF( FT_Error ) diff --git a/include/freetype/cache/ftcglyph.h b/include/freetype/cache/ftcglyph.h index b0a4ea7e7..ca70492b1 100644 --- a/include/freetype/cache/ftcglyph.h +++ b/include/freetype/cache/ftcglyph.h @@ -2,7 +2,7 @@ /* */ /* ftcglyph.h */ /* */ -/* FreeType glyph image (FT_Glyph) cache (specification). */ +/* FreeType abstract glyph cache (specification). */ /* */ /* Copyright 2000 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ @@ -24,6 +24,14 @@ /* For example, see `ftcimage.h' and `ftcimage.c' which */ /* implement a FT_Glyph cache based on this code. */ /* */ + /* NOTE: for now, each glyph set is implemented as a static hash table */ + /* it's be interesting to experiment with dynamic hashes to see */ + /* if this improves performance or not (I don't know why but */ + /* something tells me it won't ?!) */ + /* */ + /* in all cases, this change should not affect any derived */ + /* glyph cache class.. */ + /* */ /*************************************************************************/ @@ -147,7 +155,7 @@ { FTC_CacheRec root; FT_Lru gsets_lru; /* static sets lru list */ - FTC_GlyphSet last_gset; /* small cache :-) */ + FTC_GlyphSet last_gset; /* small cache :o) */ } FTC_Glyph_CacheRec; diff --git a/include/freetype/cache/ftcimage.h b/include/freetype/cache/ftcimage.h new file mode 100644 index 000000000..f49333997 --- /dev/null +++ b/include/freetype/cache/ftcimage.h @@ -0,0 +1,190 @@ +/***************************************************************************/ +/* */ +/* ftcimage.c */ +/* */ +/* FreeType Image cache (body). */ +/* */ +/* Each image cache really manages FT_Glyph objects :-) */ +/* */ +/* */ +/* 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 +#include + +#ifdef __cplusplus + extern "C" { +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** IMAGE CACHE OBJECT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#define FTC_IMAGE_FORMAT( x ) ( (x) & 7 ) + + /*************************************************************************/ + /* */ + /* */ + /* FTC_Image_Type */ + /* */ + /* */ + /* An enumeration used to list the types of glyph images found in a */ + /* glyph image cache. */ + /* */ + /* */ + /* ftc_image_mono :: Monochrome bitmap glyphs. */ + /* */ + /* ftc_image_grays :: Anti-aliased bitmap glyphs. */ + /* */ + /* ftc_image_outline :: Scaled (and hinted) outline glyphs. */ + /* */ + /* ftc_master_outline :: Unscaled original outline glyphs. */ + /* */ + /* */ + /* Other types may be defined in the future. */ + /* */ + typedef enum FTC_Image_Type_ + { + ftc_image_format_bitmap = 0, + ftc_image_format_outline = 1, + + ftc_image_flag_monochrome = 16, + ftc_image_flag_unhinted = 32, + ftc_image_flag_autohinted = 64, + ftc_image_flag_unscaled = 128, + ftc_image_flag_no_sbits = 256, + + ftc_image_mono = ftc_image_format_bitmap | + ftc_image_flag_monochrome, /* monochrome bitmap */ + ftc_image_grays = ftc_image_format_bitmap, /* anti-aliased bitmap */ + ftc_image_outline = ftc_image_format_outline /* scaled outline */ + + } FTC_Image_Type; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_Image_Desc */ + /* */ + /* */ + /* A simple structure used to describe a given glyph image category. */ + /* */ + /* */ + /* size :: An FTC_SizeRec used to describe the glyph's face & */ + /* size. */ + /* */ + /* image_type :: The glyph image's type. */ + /* */ + typedef struct FTC_Image_Desc_ + { + FTC_FontRec font; + FT_UInt image_type; + + } FTC_Image_Desc; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_Image_Cache */ + /* */ + /* */ + /* A handle to an glyph image cache object. They are designed to */ + /* hold many distinct glyph images, while not exceeding a certain */ + /* memory threshold. */ + /* */ + typedef struct FTC_Image_CacheRec_* FTC_Image_Cache; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_Image_Cache_New */ + /* */ + /* */ + /* Creates a new glyph image cache. */ + /* */ + /* */ + /* manager :: The parent manager for the image cache. */ + /* */ + /* */ + /* acache :: A handle to the new glyph image cache object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT_DEF( FT_Error ) FTC_Image_Cache_New( FTC_Manager manager, + FTC_Image_Cache* acache ); + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_Image_Cache_Lookup */ + /* */ + /* */ + /* Retrieves a given glyph image from a glyph image cache. */ + /* */ + /* */ + /* cache :: A handle to the source glyph image cache. */ + /* */ + /* desc :: A pointer to a glyph image descriptor. */ + /* */ + /* gindex :: The glyph index to retrieve. */ + /* */ + /* */ + /* aglyph :: The corresponding FT_Glyph object. 0 in case of */ + /* failure. */ + /* */ + /* */ + /* error code, 0 means success */ + /* */ + /* */ + /* the returned glyph is owned and manager by the glyph image cache. */ + /* Never try to transform or discard it manually! You can however */ + /* create a copy with FT_Glyph_Copy() and modify the new one. */ + /* */ + /* Because the glyph image cache limits the total amount of memory */ + /* 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 ); + + + +#ifdef __cplusplus + } +#endif + + +#endif /* FTCIMAGE_H */ + + +/* END */ diff --git a/include/freetype/cache/ftcmanag.h b/include/freetype/cache/ftcmanag.h index 0b13e345a..ec899b9c4 100644 --- a/include/freetype/cache/ftcmanag.h +++ b/include/freetype/cache/ftcmanag.h @@ -73,7 +73,6 @@ #endif - /* default values */ #define FTC_MAX_FACES_DEFAULT 2 #define FTC_MAX_SIZES_DEFAULT 4 #define FTC_MAX_BYTES_DEFAULT 200000 /* 200kByte by default! */ @@ -82,6 +81,40 @@ #define FTC_MAX_CACHES 16 + /**************************************************************** + * + * FTC_ManagerRec + * + * + * the cache manager structure. Each cache manager is in + * charge of performing two tasks: + * + * + * library :: handle to FreeType library instance + * faces_lru :: lru list of FT_Face objects in cache + * sizes_lru :: lru list of FT_Size objects in cache + * + * max_bytes :: maximum number of bytes to be allocated + * in the cache. this is only related to + * the byte size of the nodes cached by + * the manager. + * + * num_bytes :: current number of bytes allocated in + * the cache. only related to the byte size + * of cached nodes. + * + * num_nodes :: current number of nodes in the manager + * + * global_lru :: the global lru list of all cache nodes + * + * caches :: a table of installed/registered cache + * objects + * + * request_data :: user-provided data passed to the requester + * request_face :: user-provided function used to implement + * a mapping between abstract FTC_FaceIDs + * and real FT_Face objects.. + */ typedef struct FTC_ManagerRec_ { FT_Library library; @@ -90,6 +123,7 @@ FT_ULong max_bytes; FT_ULong num_bytes; + FT_UInt num_nodes; FT_ListRec global_lru; FTC_Cache caches[FTC_MAX_CACHES]; @@ -99,6 +133,31 @@ } FTC_ManagerRec; + /********************************************************************** + * + * FTC_Manager_Compress + * + * + * this function is used to check the state of the cache manager + * if its "num_bytes" field is greater than its "max_bytes" + * field, this function will flush as many old cache nodes as + * possible (ignoring cache nodes with a non-zero reference + * count). + * + * + * manager :: handle to cache manager + * + * + * client applications should not call this function directly. + * it is normally invoked by specific cache implementations. + * + * the reason this function is exported is to allow client- + * specific cache classes.. + * + */ + FT_EXPORT_DEF( void ) FTC_Manager_Compress( FTC_Manager manager ); + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -138,19 +197,56 @@ #define FTC_LIST_TO_CACHENODE( n ) ( (FTC_CacheNode)(n) ) - /* return the size in bytes of a given cache node */ + /********************************************************************** + * + * FTC_CacheNode_SizeFunc + * + * + * a function used to compute the total size in bytes of a given + * cache node. It is used by the cache manager to compute the + * number of old nodes to flush when the cache is full.. + * + * + * node :: handle to target cache node + * cache_data :: a generic pointer passed to the destructor. + */ typedef FT_ULong (*FTC_CacheNode_SizeFunc)( FTC_CacheNode node, - FT_Pointer user ); + FT_Pointer cache_data ); - /* finalize a given cache node */ + /********************************************************************** + * + * FTC_CacheNode_DestroyFunc + * + * + * a function used to destroy a given cache node. It is called + * by the manager when the cache is full and old nodes need to + * be flushed out.. + * + * + * node :: handle to target cache node + * cache_data :: a generic pointer passed to the destructor. + */ typedef void (*FTC_CacheNode_DestroyFunc)( FTC_CacheNode node, - FT_Pointer user ); + FT_Pointer cache_data ); - /* This structure is used to provide functions to the cache manager. */ - /* It will use them to size and destroy cache nodes. Note that there */ - /* is no `init_node' because cache objects are entirely responsible */ - /* for the creation of new cache nodes. */ - /* */ + /********************************************************************** + * + * FTC_CacheNode_Class + * + * + * a very simple structure used to describe a cache node's class + * to the cache manager + * + * + * size_node :: a function used to size the node + * destroy_node :: a function used to destroy the node + * + * + * the cache node class doesn't include a "new_node" function + * because the cache manager never allocates cache node directly, + * it delegates this task to its cache objects.. + * + */ typedef struct FTC_CacheNode_Class_ { FTC_CacheNode_SizeFunc size_node; @@ -168,10 +264,45 @@ /*************************************************************************/ + /********************************************************************** + * + * FTC_Cache_InitFunc + * + * + * a function used to initialize a given cache object + * + * + * cache :: handle to new cache + */ typedef FT_Error (*FTC_Cache_InitFunc)( FTC_Cache cache ); + + + /********************************************************************** + * + * FTC_Cache_DoneFunc + * + * + * a function used to finalize a given cache object + * + * + * cache :: handle to target cache + */ typedef void (*FTC_Cache_DoneFunc)( FTC_Cache cache ); + /********************************************************************** + * + * FTC_Cache_Class + * + * + * a structure used to describe a given cache object class to + * the cache manager. + * + * + * cache_byte_size :: size of cache object in bytes + * init_cache :: cache object initializer + * done_cache :: cache object finalizer + */ struct FTC_Cache_Class_ { FT_UInt cache_byte_size; @@ -179,6 +310,23 @@ FTC_Cache_DoneFunc done_cache; }; + + /********************************************************************** + * + * FTC_CacheRec + * + * + * a structure used to describe an abstract cache object + * + * + * manager :: handle to parent cache manager + * memory :: handle to memory manager + * clazz :: pointer to cache clazz + * node_clazz :: pointer to cache's node clazz + * + * cache_index :: index of cache in manager's table + * cache_data :: data passed to the cache node constructor/finalizer + */ typedef struct FTC_CacheRec_ { FTC_Manager manager; @@ -187,16 +335,11 @@ FTC_CacheNode_Class* node_clazz; FT_UInt cache_index; /* in manager's table */ - FT_Pointer cache_user; /* passed to cache node methods */ + FT_Pointer cache_data; /* passed to cache node methods */ } FTC_CacheRec; - /* `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. */ - FT_EXPORT_DEF( void ) FTC_Manager_Compress( FTC_Manager manager ); - #ifdef __cplusplus } diff --git a/src/cache/ftcsbits.h b/include/freetype/cache/ftcsbits.h similarity index 81% rename from src/cache/ftcsbits.h rename to include/freetype/cache/ftcsbits.h index 9e395ec1e..d9d801150 100644 --- a/src/cache/ftcsbits.h +++ b/include/freetype/cache/ftcsbits.h @@ -32,49 +32,24 @@ typedef struct FTC_SBit_CacheRec_* FTC_SBit_Cache; - /* format of small bitmaps */ - typedef enum FTC_SBit_Format_ - { - ftc_sbit_format_mono = 0, - ftc_sbit_format_aa256 = 1, - - } FTC_SBit_Format; - - /* a compact structure used to hold a single small bitmap */ typedef struct FTC_SBitRec_ { FT_Byte width; FT_Byte height; - FT_SChar left; - FT_SChar top; + FT_Char left; + FT_Char top; FT_Byte format; - FT_SChar pitch; - FT_SChar xadvance; - FT_SChar yadvance; + FT_Char pitch; + FT_Char xadvance; + FT_Char yadvance; FT_Byte* buffer; } FTC_SBitRec; - typedef struct FTC_SBitSetRec_ - { - FTC_ChunkSetRec root; - FTC_Image_Desc desc; - - } FTC_SBitSet; - - - typedef struct FTC_SBit_CacheRec_ - { - FTC_Chunk_CacheRec root; - - } FTC_SBit_CacheRec; - - - FT_EXPORT_DEF( FT_Error ) FTC_SBit_Cache_New( FTC_Manager manager, FTC_SBit_Cache *acache ); @@ -83,6 +58,7 @@ FT_EXPORT_DEF( FT_Error ) FTC_SBit_Cache_Lookup( FTC_SBit_Cache cache, FTC_Image_Desc* desc, + FT_UInt gindex, FTC_SBit *sbit ); diff --git a/include/freetype/cache/ftlru.h b/include/freetype/cache/ftlru.h index d514fd38f..9e81681ad 100644 --- a/include/freetype/cache/ftlru.h +++ b/include/freetype/cache/ftlru.h @@ -72,7 +72,7 @@ typedef FT_Pointer FT_LruKey; - /* an lru node -- node.root.data points to the element */ + /* an lru node -- root.data points to the element */ typedef struct FT_LruNodeRec_ { FT_ListNodeRec root; @@ -80,6 +80,8 @@ } FT_LruNodeRec, *FT_LruNode; + + /* forward declaration */ typedef struct FT_LruRec_* FT_Lru; @@ -94,8 +96,8 @@ FT_LruNode node ); /* this method is used to finalize a given list element node */ - void (*done_element)( FT_Lru lru, - FT_LruNode node ); + void (*done_element)( FT_Lru lru, + FT_LruNode node ); /* If defined, this method is called when the list if full */ /* during the lookup process -- it is used to change the contents */ @@ -145,10 +147,11 @@ FT_Memory memory, FT_Bool pre_alloc, FT_Lru* alru ); - - FT_EXPORT_DEF( void ) FT_Lru_Reset( FT_Lru lru ); - - FT_EXPORT_DEF( void ) FT_Lru_Done( FT_Lru lru ); + + FT_EXPORT_DEF( void ) FT_Lru_Reset( FT_Lru lru ); + + FT_EXPORT_DEF( void ) FT_Lru_Done ( FT_Lru lru ); + FT_EXPORT_DEF( FT_Error ) FT_Lru_Lookup_Node( FT_Lru lru, FT_LruKey key, @@ -157,7 +160,8 @@ FT_EXPORT_DEF( FT_Error ) FT_Lru_Lookup( FT_Lru lru, FT_LruKey key, FT_Pointer* aobject ); - + + FT_EXPORT_DEF( void ) FT_Lru_Remove_Node( FT_Lru lru, FT_LruNode node ); diff --git a/include/freetype/ftcache.h b/include/freetype/ftcache.h index b7657e71d..565598b47 100644 --- a/include/freetype/ftcache.h +++ b/include/freetype/ftcache.h @@ -90,6 +90,11 @@ /* */ /* FreeType error code. 0 means success. */ /* */ + /* */ + /* the face requester should not perform funny things on the returned */ + /* face object, like creating a new FT_Size for it, or setting a */ + /* transform through FT_Set_Transform !! */ + /* */ typedef FT_Error (*FTC_Face_Requester)( FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, @@ -307,7 +312,7 @@ FTC_Font font, FT_Face* aface, FT_Size* asize ); - + /* a cache class is used to describe a unique cache type to the manager */ typedef struct FTC_Cache_Class_ FTC_Cache_Class; @@ -321,153 +326,6 @@ FTC_Cache* acache ); - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** IMAGE CACHE OBJECT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#define FTC_IMAGE_FORMAT( x ) ( (x) & 7 ) - - /*************************************************************************/ - /* */ - /* */ - /* FTC_Image_Type */ - /* */ - /* */ - /* An enumeration used to list the types of glyph images found in a */ - /* glyph image cache. */ - /* */ - /* */ - /* ftc_image_mono :: Monochrome bitmap glyphs. */ - /* */ - /* ftc_image_grays :: Anti-aliased bitmap glyphs. */ - /* */ - /* ftc_image_outline :: Scaled (and hinted) outline glyphs. */ - /* */ - /* ftc_master_outline :: Unscaled original outline glyphs. */ - /* */ - /* */ - /* Other types may be defined in the future. */ - /* */ - typedef enum FTC_Image_Type_ - { - ftc_image_format_bitmap = 0, - ftc_image_format_outline = 1, - - ftc_image_flag_monochrome = 16, - ftc_image_flag_unhinted = 32, - ftc_image_flag_autohinted = 64, - ftc_image_flag_unscaled = 128, - ftc_image_flag_no_sbits = 256, - - ftc_image_mono = ftc_image_format_bitmap | - ftc_image_flag_monochrome, /* monochrome bitmap */ - ftc_image_grays = ftc_image_format_bitmap, /* anti-aliased bitmap */ - ftc_image_outline = ftc_image_format_outline /* scaled outline */ - - } FTC_Image_Type; - - - /*************************************************************************/ - /* */ - /* */ - /* FTC_Image_Desc */ - /* */ - /* */ - /* A simple structure used to describe a given glyph image category. */ - /* */ - /* */ - /* size :: An FTC_SizeRec used to describe the glyph's face & */ - /* size. */ - /* */ - /* image_type :: The glyph image's type. */ - /* */ - typedef struct FTC_Image_Desc_ - { - FTC_FontRec font; - FT_UInt image_type; - - } FTC_Image_Desc; - - - /*************************************************************************/ - /* */ - /* */ - /* FTC_Image_Cache */ - /* */ - /* */ - /* A handle to an glyph image cache object. They are designed to */ - /* hold many distinct glyph images, while not exceeding a certain */ - /* memory threshold. */ - /* */ - typedef struct FTC_Image_CacheRec_* FTC_Image_Cache; - - - /*************************************************************************/ - /* */ - /* */ - /* FTC_Image_Cache_New */ - /* */ - /* */ - /* Creates a new glyph image cache. */ - /* */ - /* */ - /* manager :: The parent manager for the image cache. */ - /* */ - /* */ - /* acache :: A handle to the new glyph image cache object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FTC_Image_Cache_New( FTC_Manager manager, - FTC_Image_Cache* acache ); - - - /*************************************************************************/ - /* */ - /* */ - /* FTC_Image_Cache_Lookup */ - /* */ - /* */ - /* Retrieves a given glyph image from a glyph image cache. */ - /* */ - /* */ - /* cache :: A handle to the source glyph image cache. */ - /* */ - /* desc :: A pointer to a glyph image descriptor. */ - /* */ - /* gindex :: The glyph index to retrieve. */ - /* */ - /* */ - /* aglyph :: The corresponding FT_Glyph object. 0 in case of */ - /* failure. */ - /* */ - /* */ - /* error code, 0 means success */ - /* */ - /* */ - /* the returned glyph is owned and manager by the glyph image cache. */ - /* Never try to transform or discard it manually! You can however */ - /* create a copy with FT_Glyph_Copy() and modify the new one. */ - /* */ - /* Because the glyph image cache limits the total amount of memory */ - /* 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 ); - - #ifdef __cplusplus } #endif diff --git a/src/cache/ftcache.c b/src/cache/ftcache.c index 913dba4ab..f5cf47bd5 100644 --- a/src/cache/ftcache.c +++ b/src/cache/ftcache.c @@ -23,14 +23,18 @@ #include "ftlru.c" #include "ftcmanag.c" #include "ftcglyph.c" +#include "ftcchunk.c" #include "ftcimage.c" +#include "ftcsbits.c" #else #include #include #include +#include #include +#include #endif diff --git a/src/cache/ftcchunk.c b/src/cache/ftcchunk.c index 2dc5b2439..c05a6f2d6 100644 --- a/src/cache/ftcchunk.c +++ b/src/cache/ftcchunk.c @@ -16,7 +16,7 @@ /***************************************************************************/ -#include +#include #include #include #include @@ -33,7 +33,7 @@ /* create a new chunk node, setting its cache index and ref count */ - FT_EXPORT_FUNC( NV_Error ) + FT_EXPORT_FUNC( FT_Error ) FTC_ChunkNode_Init( FTC_ChunkNode node, FTC_ChunkSet cset, FT_UInt index, @@ -41,22 +41,25 @@ { FTC_Chunk_Cache cache = cset->cache; FTC_CacheNode_Data* data = FTC_CACHENODE_TO_DATA_P( &node->root ); - NV_Error error = 0; + FT_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; + node->num_elements = (index+1 < cset->element_count) + ? cset->element_count * cset->element_size + : cset->element_max - cset->element_count*index; if (alloc) { /* allocate elements array */ + FT_Memory memory; + + memory = cache->root.memory; - error = MEM_ALLOC( cache->elements, cset->element_size * - cset->element_count ); + error = MEM_Alloc( node->elements, cset->element_size * + cset->element_count ); } return error; } @@ -79,7 +82,7 @@ FTC_ChunkSet cset = node->cset; - return cset->clazz->size_node( node, cset ); + return cset->clazz->size_node( node ); } @@ -102,9 +105,6 @@ 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; @@ -121,19 +121,22 @@ *aset = 0; - if ( ALLOC( set, clazz->cset_byte_size ) ) + if ( ALLOC( cset, 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; + /* now compute element_max, element_count and element_size */ + error = clazz->sizes( cset, type); + if (error) + goto Exit; + /* compute maximum number of nodes */ - cset->num_chunks = (num_elements + (chunk_size-1))/chunk_size; + cset->num_chunks = (cset->element_max + + cset->element_count - 1) / cset->element_count; /* allocate chunk pointers table */ if ( ALLOC_ARRAY( cset->chunks, cset->num_chunks, FTC_ChunkNode ) ) @@ -165,7 +168,7 @@ 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 = cset->chunks; FTC_ChunkNode* bucket_limit = bucket + cset->num_chunks; FT_Memory memory = cache->root.memory; @@ -181,6 +184,7 @@ lrunode = FTC_CHUNKNODE_TO_LRUNODE( node ); manager->num_bytes -= clazz->size_node( node ); + manaher->num_nodes --; FT_List_Remove( glyphs_lru, lrunode ); @@ -201,21 +205,21 @@ FTC_ChunkSet_Lookup_Node( FTC_ChunkSet cset, FT_UInt glyph_index, FTC_ChunkNode *anode, - FTC_UInt *index ) + FT_UInt *aindex ) { - FTC_Glyph_Cache cache = cset->cache; + FTC_Chunk_Cache cache = cset->cache; FTC_Manager manager = cache->root.manager; FT_Error error = 0; - FTC_GlyphSet_Class* clazz = cset->clazz; + FTC_ChunkSet_Class* clazz = cset->clazz; *anode = 0; - if (glyph_index >= cset->elements_max) + if (glyph_index >= cset->element_max) error = FT_Err_Invalid_Argument; else { - FT_UInt chunk_size = cset->chunk_size; + FT_UInt chunk_size = cset->element_count; FT_UInt chunk_index = glyph_index/chunk_size; FTC_ChunkNode* pnode = cset->chunks + chunk_index; FTC_ChunkNode node = *pnode; @@ -233,7 +237,8 @@ /* insert the node at the start the global LRU glyph list */ FT_List_Insert( &manager->global_lru, FTC_CHUNKNODE_TO_LRUNODE( node ) ); - manager->num_bytes += clazz->size_node( node, gset ); + manager->num_bytes += clazz->size_node( node ); + manager->num_nodes ++; if (manager->num_bytes > manager->max_bytes) { @@ -287,7 +292,7 @@ { /* good, now set the set index within the set object */ cset->cset_index = node - lru->nodes; - node->root.data = set; + node->root.data = cset; } return error; @@ -347,15 +352,8 @@ cache->root.node_clazz = (FTC_CacheNode_Class*)&ftc_chunk_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_chunk_set_lru_class, - FTC_MAX_GLYPH_CSETS, + FTC_MAX_CHUNK_SETS, cache, memory, 1, /* pre_alloc == TRUE */ diff --git a/src/cache/ftcglyph.c b/src/cache/ftcglyph.c index 6f897c831..27ce5d2fd 100644 --- a/src/cache/ftcglyph.c +++ b/src/cache/ftcglyph.c @@ -50,9 +50,9 @@ /* 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'. Thus be */ + /* second argument is always `cache.cache_data'. Thus be */ /* certain that the function FTC_Glyph_Cache_New() does indeed */ - /* set its `user_data' field correctly, otherwise bad things */ + /* set its `cache_data' field correctly, otherwise bad things */ /* will happen! */ FT_EXPORT_FUNC( void ) FTC_GlyphNode_Destroy( FTC_GlyphNode node, @@ -120,7 +120,7 @@ /*************************************************************************/ /*************************************************************************/ /***** *****/ - /***** GLYPH QUEUES *****/ + /***** GLYPH SETS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ @@ -204,6 +204,7 @@ lrunode = FTC_GLYPHNODE_TO_LRUNODE( node ); manager->num_bytes -= clazz->size_node( node, gset ); + manager->num_nodes --; FT_List_Remove( glyphs_lru, lrunode ); @@ -273,6 +274,7 @@ FT_List_Insert( &manager->global_lru, FTC_GLYPHNODE_TO_LRUNODE( node ) ); manager->num_bytes += clazz->size_node( node, gset ); + manager->num_nodes ++; if (manager->num_bytes > manager->max_bytes) { @@ -365,7 +367,7 @@ /*************************************************************************/ /*************************************************************************/ /***** *****/ - /***** GLYPH IMAGE CACHE OBJECTS *****/ + /***** GLYPH CACHE OBJECTS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ @@ -383,10 +385,10 @@ /* 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 */ + /* through the cache manager is `cache_data' and must be set to */ /* `cache' here. */ /* */ - cache->root.cache_user = cache; + cache->root.cache_data = cache; error = FT_Lru_New( &ftc_glyph_set_lru_class, FTC_MAX_GLYPH_SETS, diff --git a/src/cache/ftcimage.c b/src/cache/ftcimage.c index 50d0a0706..5d504e59d 100644 --- a/src/cache/ftcimage.c +++ b/src/cache/ftcimage.c @@ -16,15 +16,36 @@ /***************************************************************************/ -#ifdef FT_FLAT_COMPILE -# include "ftcimage.h" -#else -# include -#endif +#include +#include #include -#include + + /* the FT_Glyph image "glyph node" type */ + typedef struct FTC_GlyphImageRec_ + { + FTC_GlyphNodeRec root; + FT_Glyph ft_glyph; + + } FTC_GlyphImageRec, *FTC_GlyphImage; + + + /* the glyph image queue type */ + typedef struct FTC_ImageSetRec_ + { + FTC_GlyphSetRec root; + FTC_Image_Desc description; + + } FTC_ImageSetRec, *FTC_ImageSet; + + + typedef struct FTC_Image_CacheRec_ + { + FTC_Glyph_CacheRec root; + + } FTC_Image_CacheRec; + /*************************************************************************/ @@ -180,7 +201,7 @@ /*************************************************************************/ /*************************************************************************/ /***** *****/ - /***** GLYPH IMAGE QUEUES *****/ + /***** GLYPH IMAGE SETS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ diff --git a/src/cache/ftcimage.h b/src/cache/ftcimage.h index fbb2406c4..f49333997 100644 --- a/src/cache/ftcimage.h +++ b/src/cache/ftcimage.h @@ -4,6 +4,9 @@ /* */ /* FreeType Image cache (body). */ /* */ +/* Each image cache really manages FT_Glyph objects :-) */ +/* */ +/* */ /* Copyright 2000 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -23,34 +26,157 @@ #include #include - #ifdef __cplusplus extern "C" { #endif - /* the FT_Glyph image "glyph node" type */ - typedef struct FTC_GlyphImageRec_ + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** IMAGE CACHE OBJECT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#define FTC_IMAGE_FORMAT( x ) ( (x) & 7 ) + + /*************************************************************************/ + /* */ + /* */ + /* FTC_Image_Type */ + /* */ + /* */ + /* An enumeration used to list the types of glyph images found in a */ + /* glyph image cache. */ + /* */ + /* */ + /* ftc_image_mono :: Monochrome bitmap glyphs. */ + /* */ + /* ftc_image_grays :: Anti-aliased bitmap glyphs. */ + /* */ + /* ftc_image_outline :: Scaled (and hinted) outline glyphs. */ + /* */ + /* ftc_master_outline :: Unscaled original outline glyphs. */ + /* */ + /* */ + /* Other types may be defined in the future. */ + /* */ + typedef enum FTC_Image_Type_ { - FTC_GlyphNodeRec root; - FT_Glyph ft_glyph; + ftc_image_format_bitmap = 0, + ftc_image_format_outline = 1, - } FTC_GlyphImageRec, *FTC_GlyphImage; + ftc_image_flag_monochrome = 16, + ftc_image_flag_unhinted = 32, + ftc_image_flag_autohinted = 64, + ftc_image_flag_unscaled = 128, + ftc_image_flag_no_sbits = 256, + + ftc_image_mono = ftc_image_format_bitmap | + ftc_image_flag_monochrome, /* monochrome bitmap */ + ftc_image_grays = ftc_image_format_bitmap, /* anti-aliased bitmap */ + ftc_image_outline = ftc_image_format_outline /* scaled outline */ + + } FTC_Image_Type; - /* the glyph image queue type */ - typedef struct FTC_ImageSetRec_ + /*************************************************************************/ + /* */ + /* */ + /* FTC_Image_Desc */ + /* */ + /* */ + /* A simple structure used to describe a given glyph image category. */ + /* */ + /* */ + /* size :: An FTC_SizeRec used to describe the glyph's face & */ + /* size. */ + /* */ + /* image_type :: The glyph image's type. */ + /* */ + typedef struct FTC_Image_Desc_ { - FTC_GlyphSetRec root; - FTC_Image_Desc description; - - } FTC_ImageSetRec, *FTC_ImageSet; + FTC_FontRec font; + FT_UInt image_type; + + } FTC_Image_Desc; - typedef struct FTC_Image_CacheRec_ - { - FTC_Glyph_CacheRec root; - - } FTC_Image_CacheRec; + /*************************************************************************/ + /* */ + /* */ + /* FTC_Image_Cache */ + /* */ + /* */ + /* A handle to an glyph image cache object. They are designed to */ + /* hold many distinct glyph images, while not exceeding a certain */ + /* memory threshold. */ + /* */ + typedef struct FTC_Image_CacheRec_* FTC_Image_Cache; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_Image_Cache_New */ + /* */ + /* */ + /* Creates a new glyph image cache. */ + /* */ + /* */ + /* manager :: The parent manager for the image cache. */ + /* */ + /* */ + /* acache :: A handle to the new glyph image cache object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT_DEF( FT_Error ) FTC_Image_Cache_New( FTC_Manager manager, + FTC_Image_Cache* acache ); + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_Image_Cache_Lookup */ + /* */ + /* */ + /* Retrieves a given glyph image from a glyph image cache. */ + /* */ + /* */ + /* cache :: A handle to the source glyph image cache. */ + /* */ + /* desc :: A pointer to a glyph image descriptor. */ + /* */ + /* gindex :: The glyph index to retrieve. */ + /* */ + /* */ + /* aglyph :: The corresponding FT_Glyph object. 0 in case of */ + /* failure. */ + /* */ + /* */ + /* error code, 0 means success */ + /* */ + /* */ + /* the returned glyph is owned and manager by the glyph image cache. */ + /* Never try to transform or discard it manually! You can however */ + /* create a copy with FT_Glyph_Copy() and modify the new one. */ + /* */ + /* Because the glyph image cache limits the total amount of memory */ + /* 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 ); + #ifdef __cplusplus diff --git a/src/cache/ftcmanag.c b/src/cache/ftcmanag.c index fe4664a0f..e1a9412ad 100644 --- a/src/cache/ftcmanag.c +++ b/src/cache/ftcmanag.c @@ -54,7 +54,8 @@ { /* destroy initial size object; it will be re-created later */ face = (FT_Face)node->root.data; - FT_Done_Size( face->size ); + if (face->size) + FT_Done_Size( face->size ); } return error; @@ -310,6 +311,7 @@ FT_Lru_Reset( manager->sizes_lru ); FT_Lru_Reset( manager->faces_lru ); } + /* FIXME: flush the caches ?? */ } @@ -400,15 +402,23 @@ manager->num_bytes -= clazz->size_node( cache_node, - cache->cache_user ); + cache->cache_data ); - clazz->destroy_node( cache_node, cache->cache_user ); + clazz->destroy_node( cache_node, cache->cache_data ); } else { /* this should never happen! */ FT_ERROR(( "FTC_Manager_Compress: Cache Manager is corrupted!\n" )); } + + /* check, just in case of general corruption :-) */ + if (manager->num_nodes <= 0) + { + FT_ERROR(( "FTC_Manager_Compress: invalid cache node count !!\n" )); + } + else + manager->num_nodes--; } node = prev; } diff --git a/src/cache/ftcsbits.c b/src/cache/ftcsbits.c index ab897d83b..281b48bfb 100644 --- a/src/cache/ftcsbits.c +++ b/src/cache/ftcsbits.c @@ -1,9 +1,29 @@ -#include +#include +#include + +#define FTC_SBITSET_ELEMENT_COUNT 16 + + + typedef struct FTC_SBitSetRec_ + { + FTC_ChunkSetRec root; + FTC_Image_Desc desc; + + } FTC_SBitSetRec, *FTC_SBitSet; + + + typedef struct FTC_SBit_CacheRec_ + { + FTC_Chunk_CacheRec root; + + } FTC_SBit_CacheRec; + + /*************************************************************************/ /*************************************************************************/ /***** *****/ - /***** GLYPH IMAGE NODES *****/ + /***** SBIT CACHE NODES *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ @@ -20,10 +40,13 @@ for ( ; count > 0; sbit++, count-- ) FREE( sbit->buffer ); + FREE( node->elements ); FREE( node ); } + + static FT_Error ftc_bitmap_copy( FT_Memory memory, FT_Bitmap* source, @@ -48,12 +71,12 @@ LOCAL_FUNC_X FT_Error ftc_sbit_chunk_node_new( FTC_ChunkSet cset, FT_UInt index, - FTC_SBitChunk *anode ) + FTC_ChunkNode *anode ) { FT_Error error; FT_Memory memory = cset->memory; FTC_SBitSet sbitset = (FTC_SBitSet)cset; - FTC_SBitChunk node = 0; + FTC_ChunkNode node = 0; FT_Face face; FT_Size size; @@ -63,86 +86,96 @@ goto Exit; /* init its inner fields */ - error = FTC_ChunkNode_Init( FTC_CHUNKNODE(node), cset, index, 1 ); + error = FTC_ChunkNode_Init( node, cset, index, 1 ); if (error) goto Exit; - /* we will now load all glyph images */ + /* we will now load all glyph images for this chunk */ error = FTC_Manager_Lookup_Size( cset->manager, - &sbitset->description.font, + &sbitset->desc.font, &face, &size ); if ( !error ) { - FT_UInt glyph_index = index * cset->chunk_size; + FT_UInt glyph_index = index * cset->element_count; FT_UInt load_flags = FT_LOAD_DEFAULT; - FT_UInt image_type = sbitset->description.image_type; + FT_UInt image_type = sbitset->desc.image_type; FT_UInt count = node->num_elements; FTC_SBit sbit = (FTC_SBit)node->elements; - - if ( FTC_IMAGE_FORMAT( image_type ) == ftc_image_format_bitmap ) + /* determine load flags, depending on the font description's */ + /* image type.. */ { - if ( image_type & ftc_image_flag_monochrome ) - load_flags |= FT_LOAD_MONOCHROME; - - /* disable embedded bitmaps loading if necessary */ - if ( image_type & ftc_image_flag_no_sbits ) - load_flags |= FT_LOAD_NO_BITMAP; - } - else if ( FTC_IMAGE_FORMAT( image_type ) == ftc_image_format_outline ) - { - /* disable embedded bitmaps loading */ - load_flags |= FT_LOAD_NO_BITMAP; - - if ( image_type & ftc_image_flag_unscaled ) + if ( FTC_IMAGE_FORMAT( image_type ) == ftc_image_format_bitmap ) { - FT_ERROR(( "FTC_SBit_Cache: cannot load vector outlines in a" + if ( image_type & ftc_image_flag_monochrome ) + load_flags |= FT_LOAD_MONOCHROME; + + /* disable embedded bitmaps loading if necessary */ + if ( image_type & ftc_image_flag_no_sbits ) + load_flags |= FT_LOAD_NO_BITMAP; + } + else + { + FT_ERROR(( "FTC_SBit_Cache: cannot load scalable glyphs in a" " sbit cache, please check your arguments !!\n" )); - error = FT_Err_Bad_Argument; + error = FT_Err_Invalid_Argument; goto Exit; } - } - /* always render glyphs to bitmaps */ - load_flags |= FT_LOAD_RENDER; + /* always render glyphs to bitmaps */ + load_flags |= FT_LOAD_RENDER; - if ( image_type & ftc_image_flag_unhinted ) - load_flags |= FT_LOAD_NO_HINTING; + if ( image_type & ftc_image_flag_unhinted ) + load_flags |= FT_LOAD_NO_HINTING; - if ( image_type & ftc_image_flag_autohinted ) - load_flags |= FT_LOAD_FORCE_AUTOHINT; + if ( image_type & ftc_image_flag_autohinted ) + load_flags |= FT_LOAD_FORCE_AUTOHINT; + } /* load a chunk of small bitmaps in a row */ - for ( ; count > 0; count--, glyph_index++ ) + for ( ; count > 0; count--, glyph_index++, sbit++ ) { + /* by default, indicates a "missing" glyph */ + sbit->buffer = 0; + error = FT_Load_Glyph( face, glyph_index, load_flags ); if (!error) { FT_Int temp; FT_GlyphSlot slot = face->glyph; FT_Bitmap* bitmap = &slot->bitmap; - FT_Int advance; + FT_Int xadvance, yadvance; - /* check that our values fit in 8-bit containers !! */ -#define CHECK_SCHAR(d) ( temp = (FT_SChar)d, temp == d ) -#define CHECK_BYTE(d) ( temp = (FT_Byte) d, temp == d ) + /* check that our values fit in 8-bit containers !! */ + /* if this is not the case, our bitmap is too large */ + /* and we will leave it as "missing" with sbit.buffer = 0 */ + +#define CHECK_CHAR(d) ( temp = (FT_Char)d, temp == d ) +#define CHECK_BYTE(d) ( temp = (FT_Byte)d, temp == d ) - advance = (slot->metrics.horiAdvance+32) >> 6; + /* FIXME: add support for vertical layouts maybe.. */ + + /* horizontal advance in pixels */ + xadvance = (slot->metrics.horiAdvance+32) >> 6; + yadvance = (slot->metrics.vertAdvance+32) >> 6; if ( CHECK_BYTE ( bitmap->rows ) && CHECK_BYTE ( bitmap->width ) && - CHECK_SCHAR( bitmap->pitch ) && - CHECK_SCHAR( slot->bitmap_left ) && - CHECK_SCHAR( slot->bitmap_top ) && - CHECK_SCHAR( advance ) ) + CHECK_CHAR ( bitmap->pitch ) && + CHECK_CHAR ( slot->bitmap_left ) && + CHECK_CHAR ( slot->bitmap_top ) && + CHECK_CHAR ( xadvance ) && + CHECK_CHAR ( yadvance ) ) { - sbit->width = (FT_Byte) bitmap->width; - sbit->height = (FT_Byte) bitmap->height; - sbit->pitch = (FT_SChar)bitmap->pitch; - sbit->left = (FT_SChar)slot->bitmap_left; - sbit->top = (FT_SChar)slot->bitmap_top; - sbit->advance = (FT_SChar)advance; + sbit->width = (FT_Byte) bitmap->width; + sbit->height = (FT_Byte) bitmap->rows; + sbit->pitch = (FT_Char) bitmap->pitch; + sbit->left = (FT_Char) slot->bitmap_left; + sbit->top = (FT_Char) slot->bitmap_top; + sbit->xadvance = (FT_Char) xadvance; + sbit->yadvance = (FT_Char) yadvance; + sbit->format = (FT_Byte) bitmap->pixel_mode; /* grab the bitmap when possible */ if ( slot->flags & ft_glyph_own_bitmap ) @@ -157,8 +190,6 @@ } } } - else - sbit->buffer = 0; } /* ignore the errors that might have occured there */ @@ -179,46 +210,33 @@ /* this function is important because it is both part of */ - /* a FTC_ChunkSet_Class and a FTC_CacheNode_Class */ + /* a FTC_ChunkSet_Class and a FTC_CacheNode_Class */ /* */ LOCAL_FUNC_X - FT_ULong ftc_sbit_chunk_node_size( FTC_SBitChunk node ) + FT_ULong ftc_sbit_chunk_node_size( FTC_ChunkNode node ) { - FT_ULong size = 0; - FT_Glyph glyph = node->ft_glyph; + FT_ULong size; + FTC_ChunkSet cset = node->cset; + FT_UInt count = node->num_elements; + FT_Int pitch; + FTC_SBit sbit = (FTC_SBit)node->elements; + size = sizeof (*node); /* the node itself */ + size += cset->element_count * sizeof(FTC_SBitRec); /* the sbit recors */ - switch ( glyph->format ) + for ( ; count > 0; count--, sbit++ ) { - case ft_glyph_format_bitmap: + if (sbit->buffer) { - FT_BitmapGlyph bitg; - - - bitg = (FT_BitmapGlyph)glyph; - size = bitg->bitmap.rows * labs( bitg->bitmap.pitch ) + - sizeof ( *bitg ); + pitch = sbit->pitch; + if (pitch < 0) + pitch = -pitch; + + /* add the size of a given glyph image */ + size += pitch * sbit->height; } - break; - - 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; - - default: - ; } - size += sizeof ( *node ); return size; } @@ -226,26 +244,47 @@ /*************************************************************************/ /*************************************************************************/ /***** *****/ - /***** GLYPH IMAGE QUEUES *****/ + /***** SBIT CHUNK SETS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ LOCAL_FUNC_X - FT_Error ftc_image_set_init( FTC_ImageSet iset, - FTC_Image_Desc* type ) + FT_Error ftc_sbit_chunk_set_sizes( FTC_ChunkSet cset, + FTC_Image_Desc* desc ) { - iset->description = *type; + FT_Error error; + FT_Face face; + + cset->element_count = FTC_SBITSET_ELEMENT_COUNT; + cset->element_size = sizeof(FTC_SBitRec); + + /* lookup the FT_Face to obtain the number of glyphs */ + error = FTC_Manager_Lookup_Face( cset->manager, + &desc->font, &face ); + if (!error) + cset->element_max = face->num_glyphs; + + return error; + } + + + + LOCAL_FUNC_X + FT_Error ftc_sbit_chunk_set_init( FTC_SBitSet sset, + FTC_Image_Desc* type ) + { + sset->desc = *type; return 0; } LOCAL_FUNC_X - FT_Bool ftc_image_set_compare( FTC_ImageSet iset, - FTC_Image_Desc* type ) + FT_Bool ftc_sbit_chunk_set_compare( FTC_SBitSet sset, + FTC_Image_Desc* type ) { - return !memcmp( &iset->description, type, sizeof ( *type ) ); + return !memcmp( &sset->desc, type, sizeof ( *type ) ); } @@ -253,79 +292,83 @@ { sizeof( FTC_ImageSetRec ), - (FTC_ChunkSet_InitFunc) ftc_image_set_init, - (FTC_ChunkSet_DoneFunc) 0, - (FTC_ChunkSet_CompareFunc) ftc_image_set_compare, + (FTC_ChunkSet_InitFunc) ftc_sbit_chunk_set_init, + (FTC_ChunkSet_DoneFunc) 0, + (FTC_ChunkSet_CompareFunc) ftc_sbit_chunk_set_compare, + (FTC_ChunkSet_SizesFunc) ftc_sbit_chunk_set_sizes, - (FTC_ChunkSet_NewNodeFunc) ftc_sbit_chunk_node_new, - (FTC_ChunkSet_SizeNodeFunc) ftc_sbit_chunk_node_size, - (FTC_ChunkSet_DestroyNodeFunc)ftc_sbit_chunk_node_destroy + (FTC_ChunkSet_NewNodeFunc) ftc_sbit_chunk_node_new, + (FTC_ChunkSet_SizeNodeFunc) ftc_sbit_chunk_node_size, + (FTC_ChunkSet_DestroyNodeFunc) ftc_sbit_chunk_node_destroy }; /*************************************************************************/ /*************************************************************************/ /***** *****/ - /***** GLYPH IMAGE CACHE *****/ + /***** SBITS CACHE *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ - FT_CPLUSPLUS( const FTC_Glyph_Cache_Class ) ftc_sbit_chunk_cache_class = + FT_CPLUSPLUS( const FTC_Chunk_Cache_Class ) ftc_sbit_cache_class = { { - sizeof( FTC_Image_CacheRec ), - (FTC_Cache_InitFunc) FTC_Glyph_Cache_Init, - (FTC_Cache_DoneFunc) FTC_Glyph_Cache_Done + sizeof( FTC_SBit_CacheRec ), + (FTC_Cache_InitFunc) FTC_Chunk_Cache_Init, + (FTC_Cache_DoneFunc) FTC_Chunk_Cache_Done }, (FTC_ChunkSet_Class*) &ftc_sbit_chunk_set_class }; - FT_EXPORT_FUNC( FT_Error ) FTC_Image_Cache_New( FTC_Manager manager, - FTC_Image_Cache* acache ) + FT_EXPORT_FUNC( FT_Error ) + FTC_SBit_Cache_New( FTC_Manager manager, + FTC_SBit_Cache* acache ) { return FTC_Manager_Register_Cache( manager, - (FTC_Cache_Class*)&ftc_sbit_chunk_cache_class, + (FTC_Cache_Class*)&ftc_sbit_cache_class, (FTC_Cache*)acache ); } FT_EXPORT_DEF( FT_Error ) - FTC_Image_Cache_Lookup( FTC_Image_Cache cache, - FTC_Image_Desc* desc, - FT_UInt gindex, - FT_Glyph* aglyph ) + FTC_SBit_Cache_Lookup( FTC_SBit_Cache cache, + FTC_Image_Desc* desc, + FT_UInt gindex, + FTC_SBit *asbit ) { FT_Error error; - FTC_ChunkSet gset; - FTC_GlyphNode node; + FTC_ChunkSet cset; + FTC_ChunkNode node; + FT_UInt cindex; FTC_Manager manager; - FTC_ImageSet img_set; + FTC_SBitSet sset; + FTC_SBit sbit; /* check for valid `desc' delayed to FT_Lru_Lookup() */ - if ( !cache || !aglyph ) + if ( !cache || !asbit ) return FT_Err_Invalid_Argument; - *aglyph = 0; - gset = cache->root.last_gset; - img_set = (FTC_ImageSet)gset; - if ( !gset || memcmp( &img_set->description, desc, sizeof ( *desc ) ) ) + *asbit = 0; + cset = cache->root.last_cset; + sset = (FTC_SBitSet)cset; + if ( !cset || memcmp( &sset->desc, desc, sizeof ( *desc ) ) ) { - error = FT_Lru_Lookup( cache->root.gsets_lru, + error = FT_Lru_Lookup( cache->root.csets_lru, (FT_LruKey)desc, - (FT_Pointer*)&gset ); - cache->root.last_gset = gset; + (FT_Pointer*)&cset ); + cache->root.last_cset = cset; if ( error ) goto Exit; } - error = FTC_ChunkSet_Lookup_Node( gset, gindex, &node ); + error = FTC_ChunkSet_Lookup_Node( cset, gindex, &node, &cindex ); if ( error ) goto Exit; @@ -333,12 +376,19 @@ manager = cache->root.root.manager; if ( manager->num_bytes > manager->max_bytes ) { - FTC_GlyphNode_Ref ( node ); + FTC_ChunkNode_Ref ( node ); FTC_Manager_Compress( manager ); - FTC_GlyphNode_Unref ( node ); + FTC_ChunkNode_Unref ( node ); } - *aglyph = ((FTC_SBitChunk)node)->ft_glyph; + sbit = ((FTC_SBit)((FTC_ChunkNode)node)->elements) + cindex; + if (sbit->buffer == 0) + { + /* the glyph was missing, we return a NULL pointer !! */ + sbit = 0; + } + + *asbit = sbit; Exit: return error;