From 14183ea0f8b9c021400d748d7311ec2a907e9f8d Mon Sep 17 00:00:00 2001 From: David Turner Date: Wed, 5 Dec 2001 15:59:33 +0000 Subject: [PATCH] First of all, a big thanks to Werner and Antoine for their latest work !! * src/pshinter/pshalgo2.c (psh2_hint_table_init), src/pshinter/pshalgo1.c (psh1_hint_table_init): removed compiler warnings * include/freetype/cache/*, src/cache/*: yet another massive rewrite of the caching sub-system, in order to both increase performance and allow simpler cache sub-classing. As an example, the code for the image and sbit caches is now much simpler I still need to update the documentation in www/freetype2/docs/cache.html to reflect the new design though.. --- ChangeLog | 17 + include/freetype/cache/ftccache.h | 251 +++++++++ include/freetype/cache/ftcchunk.h | 168 ------- include/freetype/cache/ftcglyph.h | 182 +++---- include/freetype/cache/ftcimage.h | 152 +++++- include/freetype/cache/ftcmanag.h | 186 ++----- include/freetype/cache/ftcsbits.h | 111 +++- include/freetype/cache/ftlru.h | 28 +- include/freetype/config/ftheader.h | 2 +- include/freetype/ftcache.h | 70 ++- src/autohint/ahhint.c | 4 +- src/base/ftdbgmem.c | 4 +- src/cache/Jamfile | 2 +- src/cache/ftcache.c | 2 +- src/cache/ftcglyph.c | 167 +++--- src/cache/ftcimage.c | 238 ++++----- src/cache/ftcmanag.c | 782 +++++++++-------------------- src/cache/ftcsbits.c | 358 +++++++------ src/cache/ftlru.c | 20 +- src/cache/rules.mk | 2 +- src/pshinter/pshalgo1.c | 2 +- src/pshinter/pshalgo2.c | 9 +- 22 files changed, 1340 insertions(+), 1417 deletions(-) create mode 100644 include/freetype/cache/ftccache.h delete mode 100644 include/freetype/cache/ftcchunk.h diff --git a/ChangeLog b/ChangeLog index 8721293c0..ba173b594 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2001-12-05 David Turner + + First of all, a big thanks to Werner and Antoine for their latest work !! + + * src/pshinter/pshalgo2.c (psh2_hint_table_init), + src/pshinter/pshalgo1.c (psh1_hint_table_init): removed compiler + warnings + + * include/freetype/cache/*, src/cache/*: yet another massive rewrite of + the caching sub-system, in order to both increase performance and allow + simpler cache sub-classing. As an example, the code for the image and + sbit caches is now much simpler + + I still need to update the documentation in www/freetype2/docs/cache.html + to reflect the new design though.. + + 2001-12-05 David Krause * docs/license.txt: s/X Windows/X Window System/. diff --git a/include/freetype/cache/ftccache.h b/include/freetype/cache/ftccache.h new file mode 100644 index 000000000..b6eee1f67 --- /dev/null +++ b/include/freetype/cache/ftccache.h @@ -0,0 +1,251 @@ +#ifndef __FT_CACHE_CACHE_H__ +#define __FT_CACHE_CACHE_H__ + +FT_BEGIN_HEADER + + /* handle to cache object */ + typedef struct FTC_CacheRec_* FTC_Cache; + + + /* handle to cache class */ + typedef const struct FTC_Cache_ClassRec_* FTC_Cache_Class; + + + /* handle to cache node family */ + typedef struct FTC_FamilyRec_* FTC_Family; + + + /* handle to cache root query */ + typedef struct FTC_QueryRec_* FTC_Query; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE NODE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Each cache controls one or more cache nodes. Each node is part of */ + /* the global_lru list of the manager. Its `data' field however is used */ + /* as a reference count for now. */ + /* */ + /* A node can be anything, depending on the type of information held by */ + /* the cache. It can be an individual glyph image, a set of bitmaps */ + /* glyphs for a given size, some metrics, etc. */ + /* */ + + + /* structure size should be 20 bytes on 32-bits machines */ + typedef struct FTC_NodeRec_ + { + FTC_Node mru_next; /* circular mru list pointer */ + FTC_Node mru_prev; /* circular mru list pointer */ + FTC_Node link; /* used for hashing.. */ + FT_UInt32 hash; /* used for hashing too.. */ + FT_UShort fam_index; /* index of family the node belongs to */ + FT_Short ref_count; /* reference count for this node.. */ + + } FTC_NodeRec; + +#define FTC_NODE(x) ((FTC_Node)(x)) +#define FTC_NODE_P(x) ((FTC_Node*)(x)) + + /* can be used as a FTC_Node_DoneFunc */ + FT_EXPORT(void) + ftc_node_done( FTC_Node node, + FTC_Cache cache ); + + + /* reserved for manager's use */ + FT_EXPORT(void) + ftc_node_destroy( FTC_Node node, + FTC_Manager manager ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE QUERY DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* structure modelling a cache node query. the following fields must */ + /* all be set by the @FTC_Family_CompareFunc method of a cache's family */ + /* list */ + /* */ + typedef struct FTC_QueryRec_ + { + FTC_Family family; + FT_UFast hash; + + } FTC_QueryRec; + + +#define FTC_QUERY(x) ((FTC_Query)(x)) +#define FTC_QUERY_P(x) ((FTC_Query*)(x)) + + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE FAMILY DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct FTC_FamilyRec_ + { + FT_LruNodeRec lru; + FTC_Cache cache; + FT_UInt num_nodes; + FT_UInt fam_index; + + } FTC_FamilyRec; + +#define FTC_FAMILY(x) ((FTC_Family)(x)) +#define FTC_FAMILY_P(x) ((FTC_Family*)(x)) + + + /* must be called by any FTC_Node_InitFunc routine */ + FT_EXPORT(FT_Error) + ftc_family_init( FTC_Family family, + FTC_Query query, + FTC_Cache cache ); + + + /* can be used as a FTC_Family_DoneFunc, otherwise, must be called */ + /* by any family finalizer function.. */ + FT_EXPORT(void) + ftc_family_done( FTC_Family family ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* each cache really implements a dynamic hash table to manage its nodes */ + typedef struct FTC_CacheRec_ + { + FTC_Manager manager; + FT_Memory memory; + FTC_Cache_Class clazz; + + FT_UInt cache_index; /* in manager's table */ + FT_Pointer cache_data; /* used by cache node methods */ + + FT_UFast nodes; + FT_UFast size; + FTC_Node* buckets; + + FT_LruList_ClassRec family_class; + FT_LruList families; + + } FTC_CacheRec; + + +#define FTC_CACHE(x) ((FTC_Cache)(x)) +#define FTC_CACHE_P(x) ((FTC_Cache*)(x)) + + + /* initialize a given cache */ + typedef FT_Error (*FTC_Cache_InitFunc)( FTC_Cache cache ); + + /* clear a cache */ + typedef void (*FTC_Cache_ClearFunc)( FTC_Cache cache ); + + /* finalize a given cache */ + typedef void (*FTC_Cache_DoneFunc)( FTC_Cache cache ); + + + typedef FT_Error (*FTC_Family_InitFunc)( FTC_Family family, + FTC_Query query, + FTC_Cache cache ); + + typedef FT_Int (*FTC_Family_CompareFunc)( FTC_Family family, + FTC_Query query ); + + typedef void (*FTC_Family_DoneFunc)( FTC_Family family, + FTC_Cache cache ); + + /* initialize a new cache node */ + typedef FT_Error (*FTC_Node_InitFunc)( FTC_Node node, + FT_Pointer type, + FTC_Cache cache ); + + /* compute the weight of a given cache node */ + typedef FT_ULong (*FTC_Node_WeightFunc)( FTC_Node node, + FTC_Cache cache ); + + /* compare a node to a given key pair */ + typedef FT_Bool (*FTC_Node_CompareFunc)( FTC_Node node, + FT_Pointer key, + FTC_Cache cache ); + + /* finalize a given cache node */ + typedef void (*FTC_Node_DoneFunc)( FTC_Node node, + FTC_Cache cache ); + + + typedef struct FTC_Cache_ClassRec_ + { + FT_UInt cache_size; + FTC_Cache_InitFunc cache_init; + FTC_Cache_ClearFunc cache_clear; + FTC_Cache_DoneFunc cache_done; + + FT_UInt family_size; + FTC_Family_InitFunc family_init; + FTC_Family_CompareFunc family_compare; + FTC_Family_DoneFunc family_done; + + FT_UInt node_size; + FTC_Node_InitFunc node_init; + FTC_Node_WeightFunc node_weight; + FTC_Node_CompareFunc node_compare; + FTC_Node_DoneFunc node_done; + + } FTC_Cache_ClassRec; + + /* */ + + /* can be used directly as FTC_Cache_DoneFunc(), or called by custom */ + /* cache finalizers */ + FT_EXPORT( void ) + ftc_cache_done( FTC_Cache cache ); + + + /* can be used directly as FTC_Cache_ClearFunc(), or called by custom */ + /* cache clear routines.. */ + FT_EXPORT( void ) + ftc_cache_clear( FTC_Cache cache ); + + + /* initalize the hash table within the cache */ + FT_EXPORT( FT_Error ) + ftc_cache_init( FTC_Cache cache ); + + + /* can be called when the key's hash value has been computed */ + FT_EXPORT(FT_Error) + ftc_cache_lookup( FTC_Cache cache, + FTC_Query query, + FTC_Node *anode ); + + + + /* */ + +FT_END_HEADER + +#endif /* __FT_CACHE_CACHE_H__ */ diff --git a/include/freetype/cache/ftcchunk.h b/include/freetype/cache/ftcchunk.h deleted file mode 100644 index 8bc02a4ae..000000000 --- a/include/freetype/cache/ftcchunk.h +++ /dev/null @@ -1,168 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcchunk.h */ -/* */ -/* FreeType chunk cache (specification). */ -/* */ -/* Copyright 2000-2001 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 BETA CODE. *********/ - /********* *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#ifndef __FTCCHUNK_H__ -#define __FTCCHUNK_H__ - - -#include -#include FT_CACHE_H -#include FT_CACHE_MANAGER_H - - -FT_BEGIN_HEADER - - - /* maximum number of chunk sets in a given chunk cache */ -#define FTC_MAX_CHUNK_SETS 16 - - - typedef struct FTC_ChunkNodeRec_* FTC_ChunkNode; - typedef struct FTC_ChunkSetRec_* FTC_ChunkSet; - typedef struct FTC_ChunkCacheRec_* FTC_ChunkCache; - - typedef struct FTC_ChunkNodeRec_ - { - FTC_NodeRec node; - FTC_ChunkSet cset; - FT_UShort item_count; - FT_UShort item_start; - FT_Byte* items; - - } FTC_ChunkNodeRec; - -#define FTC_CHUNK_NODE( x ) ((FTC_ChunkNode)( x )) - - /* a chunk set is used to categorize chunks of a given type */ - typedef struct FTC_ChunkSetRec_ - { - FT_LruNodeRec lru; - FT_UFast hash; - FTC_ChunkCache ccache; - FT_Fast num_chunks; - FT_UInt item_total; /* total number of glyphs in set */ - FT_UInt item_size; /* size of each glyph item in set */ - FT_UInt item_count; /* number of glyph items per chunk */ - - } FTC_ChunkSetRec; - -#define FTC_CHUNK_SET( x ) ((FTC_ChunkSet)( x )) - -#define FTC_CHUNK_SET_MEMORY( x ) (( x )->ccache->cache.memory) - - /* the abstract chunk cache class */ - typedef struct FTC_ChunkCacheRec_ - { - FTC_CacheRec cache; - FT_LruList cset_lru; /* LRU list of chunk sets */ - - } FTC_ChunkCacheRec; - -#define FTC_CHUNK_CACHE( x ) ((FTC_ChunkCache)( x )) - - - typedef struct FTC_ChunkQueryRec_ - { - /* input */ - FT_UInt gindex; /* glyph index */ - - /* output */ - FTC_ChunkSet cset; - - } FTC_ChunkQueryRec, *FTC_ChunkQuery; - - - /*************************************************************************/ - /* */ - /* These functions are exported so that they can be called from */ - /* user-provided cache classes; otherwise, they are really part of the */ - /* cache sub-system internals. */ - /* */ - - FT_EXPORT( FT_Error ) - ftc_chunk_node_init( FTC_ChunkNode node, - FTC_ChunkSet cset, - FT_UInt index, - FT_Bool alloc ); - - /* chunk set objects */ - - FT_EXPORT( void ) - ftc_chunk_node_done( FTC_ChunkNode node ); - - - FT_EXPORT( FT_Error ) - ftc_chunk_set_init( FTC_ChunkSet cset, - FT_UInt item_size, - FT_UInt item_count, - FT_UInt item_total, - FTC_ChunkCache cache ); - - FT_EXPORT( void ) - ftc_chunk_set_done( FTC_ChunkSet cset ); - - - /* chunk cache objects */ - - FT_EXPORT( FT_Error ) - ftc_chunk_cache_init( FTC_ChunkCache cache, - FT_LruList_Class cset_class ); - - FT_EXPORT( void ) - ftc_chunk_cache_done( FTC_ChunkCache cache ); - - - FT_EXPORT( FT_Error ) - ftc_chunk_cache_lookup( FTC_ChunkCache cache, - FTC_ChunkQuery query, - FTC_ChunkNode *anode ); - - /* */ - -FT_END_HEADER - -#endif /* __FTCCHUNK_H__ */ - - -/* END */ diff --git a/include/freetype/cache/ftcglyph.h b/include/freetype/cache/ftcglyph.h index bc11c7cac..bf9108b57 100644 --- a/include/freetype/cache/ftcglyph.h +++ b/include/freetype/cache/ftcglyph.h @@ -64,85 +64,91 @@ FT_BEGIN_HEADER - /* each glyph set is caracterized by a "glyph set type" which must be */ - /* defined by sub-classes */ - typedef struct FTC_GlyphSetRec_* FTC_GlyphSet; + /* each glyph set is caracterized by a "glyph set type" which must be */ + /* defined by sub-classes.. */ + typedef struct FTC_GlyphFamilyRec_* FTC_GlyphFamily; - /* handle to a glyph cache node */ - typedef struct FTC_GlyphNodeRec_* FTC_GlyphNode; - - /* a glyph cache; its nodes are all glyph-specific */ - typedef struct FTC_GlyphCacheRec_* FTC_GlyphCache; - - /* glyph sets class handle */ - typedef const struct FTC_GlyphSet_ClassRec_* FTC_GlyphSet_Class; + /* handle to a glyph cache node */ + typedef struct FTC_GlyphNodeRec_* FTC_GlyphNode; - /* Size should be 24 bytes on 32-bit machines. */ - /* Note that the node's hash is ((gset->hash << 16) | glyph_index); */ - /* this _must_ be set properly by the glyph node initializer. */ - /* */ + /* size should be 24 + chunk size on 32-bit machines */ + /* note that the node's hash is ((gfam->hash << 16) | glyph_index) */ + /* this _must_ be set properly by the glyph node initializer.. */ + /* */ typedef struct FTC_GlyphNodeRec_ { FTC_NodeRec node; - FTC_GlyphSet gset; + FT_UShort item_count; + FT_UShort item_start; } FTC_GlyphNodeRec; -#define FTC_GLYPH_NODE( x ) ((FTC_GlyphNode)( x )) -#define FTC_GLYPH_NODE_P( x ) ((FTC_GlyphNode*)( x )) +#define FTC_GLYPH_NODE(x) ((FTC_GlyphNode)(x)) +#define FTC_GLYPH_NODE_P(x) ((FTC_GlyphNode*)(x)) - /* The glyph set structure. Each glyph set is used to model a set of */ - /* glyphs of the same "type". The type itself is defined in */ - /* sub-classes. */ - /* */ - /* For example, the "image cache" uses face_id + character_pixel_sizes + */ - /* image_format to characterize glyph sets. */ - /* */ - /* A pure "master outlines" cache would only use face_id, etc. */ - /* */ - typedef struct FTC_GlyphSetRec_ - { - FT_LruNodeRec lru; /* glyph sets are LRU nodes within */ - FTC_GlyphCache gcache; /* parent cache */ - FT_UFast hash; /* must be set by initializer! */ - FT_Fast num_glyphs; /* destroyed when 0 */ - - } FTC_GlyphSetRec; - -#define FTC_GLYPH_SET( x ) ((FTC_GlyphSet)( x )) -#define FTC_GLYPH_SET_P( x ) ((FTC_GlyphSet*)( x )) - -#define FTC_GLYPH_SET_MEMORY( x ) (( x )->gcache->cache.memory) - - - /* retrieve glyph index of glyph node */ -#define FTC_GLYPH_NODE_GINDEX( x ) \ - ((FT_UInt)(FTC_GLYPH_NODE( x )->node.hash & 0xFFFF)) - - /* the abstract glyph cache object */ - typedef struct FTC_GlyphCacheRec_ - { - FTC_CacheRec cache; - FT_LruList gset_lru; /* LRU list of glyph sets */ - - } FTC_GlyphCacheRec; - -#define FTC_GLYPH_CACHE( x ) ((FTC_GlyphCache)( x )) -#define FTC_GLYPH_CACHE_P( x ) ((FTC_GlyphCache*)( x )) - typedef struct FTC_GlyphQueryRec_ { - /* input */ + FTC_QueryRec query; FT_UInt gindex; - - /* output */ - FTC_GlyphSet gset; } FTC_GlyphQueryRec, *FTC_GlyphQuery; +#define FTC_GLYPH_QUERY(x) ((FTC_GlyphQuery)(x)) + + + + + /* a glyph set is used to categorize glyphs of a given type */ + typedef struct FTC_GlyphFamilyRec_ + { + FTC_FamilyRec family; + FT_UInt32 hash; + FT_UInt item_total; /* total number of glyphs in family */ + FT_UInt item_count; /* number of glyph items per node */ + + } FTC_GlyphFamilyRec; + + +#define FTC_GLYPH_FAMILY(x) ((FTC_GlyphFamily)(x)) +#define FTC_GLYPH_FAMILY_P(x) ((FTC_GlyphFamily*)(x)) + +#define FTC_GLYPH_FAMILY_MEMORY(x) FTC_FAMILY(x)->cache->memory + +/* each glyph node contains a 'chunk' of glyph items */ +/* translate a glyph index into a chunk index */ +#define FTC_GLYPH_FAMILY_CHUNK(gfam,gindex) \ + ( (gindex) / FTC_GLYPH_FAMILY(gfam)->item_count ) + +/* find a glyph index's chunk, and return its start index */ +/* */ +#define FTC_GLYPH_FAMILY_START(gfam,gindex) \ + ( FTC_GLYPH_FAMILY_CHUNK(gfam,gindex) * FTC_GLYPH_FAMILY(gfam)->item_count ) + +/* compute a glyph request's hash value */ +/* */ +#define FTC_GLYPH_FAMILY_HASH(gfam,gindex) \ + ((FT_UFast)( (FTC_GLYPH_FAMILY(gfam)->hash << 16) | \ + (FTC_GLYPH_FAMILY_CHUNK(gfam,gindex) & 0xFFFF) )) + +/* must be called in a FTC_Family_CompareFunc to update the query */ +/* whenever a glyph set is matched in the lookup.. or when it */ +/* is created */ +/* */ +#define FTC_GLYPH_FAMILY_FOUND(gfam,gquery) \ + do { \ + FTC_QUERY(gquery)->family = FTC_FAMILY(gfam); \ + FTC_QUERY(gquery)->hash = \ + FTC_GLYPH_FAMILY_HASH(gfam,FTC_GLYPH_QUERY(gquery)->gindex); \ + } while (0) + + +/* retrieve glyph index of glyph node */ +#define FTC_GLYPH_NODE_GINDEX(x) \ + ((FT_UInt)(FTC_GLYPH_NODE(x)->node.hash & 0xFFFF)) + /*************************************************************************/ /* */ @@ -153,44 +159,42 @@ FT_BEGIN_HEADER /* must be called by derived FTC_Node_InitFunc routines */ FT_EXPORT( void ) - ftc_glyph_node_init( FTC_GlyphNode node, - FT_UInt gindex, /* glyph index for node */ - FTC_GlyphSet gset ); + ftc_glyph_node_init( FTC_GlyphNode node, + FT_UInt gindex, /* glyph index for node */ + FTC_GlyphFamily gfam ); + + /* returns TRUE iff the query's glyph index correspond to the node */ + /* this assume that the "family" and "hash" fields of the query are */ + /* already correctly set.. */ + /* */ + FT_EXPORT( FT_Bool ) + ftc_glyph_node_compare( FTC_GlyphNode gnode, + FTC_GlyphQuery gquery ); + /* must be called by derived FTC_Node_DoneFunc routines */ FT_EXPORT( void ) - ftc_glyph_node_done( FTC_GlyphNode node ); + ftc_glyph_node_done( FTC_GlyphNode node, + FTC_Cache cache ); - /* can be used as an FTC_LruNode_InitFunc or called by sub-classes */ + /* must be called by derived FTC_Family_InitFunc, calls "ftc_family_init" */ FT_EXPORT( FT_Error ) - ftc_glyph_set_init( FTC_GlyphSet gset, - FT_LruList list ); + ftc_glyph_family_init( FTC_GlyphFamily gfam, + FT_UInt32 hash, + FT_UInt item_count, + FT_UInt item_total, + FTC_GlyphQuery gquery, + FTC_Cache cache ); + - /* can be used as an FTC_LruNode_DoneFunc or called by sub-classes */ FT_EXPORT( void ) - ftc_glyph_set_done( FTC_GlyphSet gset ); + ftc_glyph_family_done( FTC_GlyphFamily gfam ); - /* can be used as an FTC_Cache_DoneFunc or called by sub-classes */ - FT_EXPORT( void ) - ftc_glyph_cache_done( FTC_GlyphCache cache ); - - /* must be called in an FTC_Cache_InitFunc! */ - FT_EXPORT( FT_Error ) - ftc_glyph_cache_init( FTC_GlyphCache cache, - FT_LruList_Class gset_class ); - - /* can be called directly or from sub-classes */ - FT_EXPORT( FT_Error ) - ftc_glyph_cache_lookup( FTC_GlyphCache cache, - FTC_GlyphQuery query, - FTC_GlyphNode *anode ); - + /* */ + FT_END_HEADER -#endif /* __FTCGLYPH_H__ */ - - -/* END */ +#endif /* __FTC_GLYPH_H__ */ diff --git a/include/freetype/cache/ftcimage.h b/include/freetype/cache/ftcimage.h index 55e3e6c43..e27b398ef 100644 --- a/include/freetype/cache/ftcimage.h +++ b/include/freetype/cache/ftcimage.h @@ -70,16 +70,138 @@ FT_BEGIN_HEADER ftc_image_flag_monochrome /* anti-aliased bitmap */ #define ftc_image_grays ftc_image_format_bitmap + /* scaled outline */ #define ftc_image_outline ftc_image_format_outline + /*************************************************************************/ + /* */ + /* */ + /* FTC_ImageDesc */ + /* */ + /* */ + /* A simple structure used to describe a given glyph image category. */ + /* note that this is different from @FTC_Image_Desc */ + /* */ + /* */ + /* size :: An FTC_SizeRec used to describe the glyph's face & */ + /* size. */ + /* */ + /* type :: The glyph image's type. note that it's a 32-bit uint */ + /* */ + /* */ + /* this type deprecates @FTC_Image_Desc */ + /* */ + typedef struct FTC_ImageDesc_ + { + FTC_FontRec font; + FT_UInt32 type; + + } FTC_ImageDesc; + + /* */ +#define FTC_IMAGE_DESC_COMPARE( d1, d2 ) \ + ( FTC_FONT_COMPARE( &(d1)->font, &(d2)->font ) && \ + (d1)->type == (d2)->type ) + +#define FTC_IMAGE_DESC_HASH(d) \ + (FT_UFast)( FTC_FONT_HASH(&(d)->font) ^ \ + ((d)->type << 4) ) + + /*************************************************************************/ + /* */ + /* */ + /* FTC_ImageCache */ + /* */ + /* */ + /* 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_ImageCacheRec_* FTC_ImageCache; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_ImageCache_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( FT_Error ) + FTC_ImageCache_New( FTC_Manager manager, + FTC_ImageCache *acache ); + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_ImageCache_Lookup */ + /* */ + /* */ + /* Retrieves a given glyph image from a glyph image cache */ + /* and 'acquire' it. This prevents the glyph image from being */ + /* flushed out of the cache, until @FTC_Image_Cache_Release is */ + /* called */ + /* */ + /* */ + /* 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. */ + /* */ + /* anode :: an opaque cache node pointer that will be used */ + /* to release the glyph once it becomes unuseful. */ + /* can be NULL, in which case this function will */ + /* have the same effect than @FTC_Image_Cache_Lookup */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* The returned glyph is owned and managed 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. */ + /* */ + /* if 'anode' is NULL */ + /* */ + /* 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( FT_Error ) + FTC_ImageCache_Lookup( FTC_ImageCache cache, + FTC_ImageDesc* desc, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ); + + /* */ + + /*************************************************************************/ /* */ /* */ /* FTC_Image_Desc */ /* */ /* */ + /* THIS TYPE IS DEPRECATED. USE @FTC_ImageDesc instead.. */ /* A simple structure used to describe a given glyph image category. */ /* */ /* */ @@ -88,6 +210,9 @@ FT_BEGIN_HEADER /* */ /* image_type :: The glyph image's type. */ /* */ + /* */ + /* */ + /* */ typedef struct FTC_Image_Desc_ { FTC_FontRec font; @@ -96,27 +221,16 @@ FT_BEGIN_HEADER } FTC_Image_Desc; - /* */ -#define FTC_IMAGE_DESC_COMPARE( d1, d2 ) \ - ( FTC_FONT_COMPARE( &(d1)->font, &(d2)->font ) && \ - (d1)->image_type == (d2)->image_type ) - -#define FTC_IMAGE_DESC_HASH( d ) \ - (FT_UFast)( FTC_FONT_HASH(&(d)->font) ^ \ - ((d)->image_type << 4) ) - - /*************************************************************************/ /* */ /* */ /* 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. */ + /* THIS TYPE IS DEPRECATED, USE @FTC_ImageCache instead */ /* */ - typedef struct FTC_Image_CacheRec_* FTC_Image_Cache; + typedef FTC_ImageCache FTC_Image_Cache; + /*************************************************************************/ @@ -125,6 +239,7 @@ FT_BEGIN_HEADER /* FTC_Image_Cache_New */ /* */ /* */ + /* THIS FUNCTION IS DEPRECATED, USE @FTC_ImageCache_New instead */ /* Creates a new glyph image cache. */ /* */ /* */ @@ -147,7 +262,7 @@ FT_BEGIN_HEADER /* FTC_Image_Cache_Lookup */ /* */ /* */ - /* Retrieves a given glyph image from a glyph image cache. */ + /* THIS FUNCTION IS DEPRECATED. USE @FTC_ImageCache_Lookup instead */ /* */ /* */ /* cache :: A handle to the source glyph image cache. */ @@ -172,15 +287,16 @@ FT_BEGIN_HEADER /* taken by the glyphs it holds, the returned glyph might disappear */ /* on a later invocation of this function! It's a cache after all... */ /* */ + /* use @FTC_ImageCache_Lookup to "lock" the glyph as long as you */ + /* need it.. */ + /* */ FT_EXPORT( FT_Error ) FTC_Image_Cache_Lookup( FTC_Image_Cache cache, FTC_Image_Desc* desc, FT_UInt gindex, FT_Glyph *aglyph ); - - /* */ - + /* */ FT_END_HEADER diff --git a/include/freetype/cache/ftcmanag.h b/include/freetype/cache/ftcmanag.h index edc092db9..aa32cd019 100644 --- a/include/freetype/cache/ftcmanag.h +++ b/include/freetype/cache/ftcmanag.h @@ -66,7 +66,7 @@ #include #include FT_CACHE_H #include FT_CACHE_INTERNAL_LRU_H - +#include FT_CACHE_INTERNAL_CACHE_H FT_BEGIN_HEADER @@ -81,21 +81,42 @@ FT_BEGIN_HEADER #define FTC_MAX_FACES_DEFAULT 2 #define FTC_MAX_SIZES_DEFAULT 4 -#define FTC_MAX_BYTES_DEFAULT 100000L /* 100kByte by default! */ +#define FTC_MAX_BYTES_DEFAULT 200000L /* ~200 KB bytes by default */ /* maximum number of caches registered in a single manager */ #define FTC_MAX_CACHES 16 - /* handle to cache object */ - typedef struct FTC_CacheRec_* FTC_Cache; + typedef struct FTC_FamilyEntryRec_ + { + FTC_Family family; + FTC_Cache cache; + FT_UInt index; + FT_UInt link; - /* handle to cache class */ - typedef const struct FTC_Cache_ClassRec_* FTC_Cache_Class; + } FTC_FamilyEntryRec, *FTC_FamilyEntry; - /* handle to cache node */ - typedef struct FTC_NodeRec_* FTC_Node; +#define FTC_FAMILY_ENTRY_NONE ((FT_UInt)-1) + typedef struct FTC_FamilyTableRec_ + { + FT_UInt count; + FT_UInt size; + FTC_FamilyEntry entries; + FT_UInt free; + + } FTC_FamilyTableRec, *FTC_FamilyTable; + + + FT_LOCAL FT_Error + ftc_family_table_alloc( FTC_FamilyTable table, + FT_Memory memory, + FTC_FamilyEntry *aentry ); + + + FT_LOCAL void + ftc_family_table_free( FTC_FamilyTable table, + FT_UInt index ); /*************************************************************************/ @@ -146,6 +167,8 @@ FT_BEGIN_HEADER FT_Pointer request_data; FTC_Face_Requester request_face; + FTC_FamilyTableRec families; + } FTC_ManagerRec; @@ -174,116 +197,6 @@ FT_BEGIN_HEADER FTC_Manager_Compress( FTC_Manager manager ); - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CACHE NODE DEFINITIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Each cache controls one or more cache nodes. Each node is part of */ - /* the global_lru list of the manager. Its `data' field however is used */ - /* as a reference count for now. */ - /* */ - /* A node can be anything, depending on the type of information held by */ - /* the cache. It can be an individual glyph image, a set of bitmaps */ - /* glyphs for a given size, some metrics, etc. */ - /* */ - - - /* structure size should be 20 bytes on 32-bits machines */ - typedef struct FTC_NodeRec_ - { - FTC_Node mru_next; /* circular mru list pointer */ - FTC_Node mru_prev; /* circular mru list pointer */ - FTC_Node link; /* used for hashing */ - FT_UInt32 hash; /* used for hashing too */ - FT_UShort cache_index; /* index of cache the node belongs to */ - FT_Short ref_count; /* reference count for this node */ - - } FTC_NodeRec; - -#define FTC_NODE( x ) ((FTC_Node)( x )) -#define FTC_NODE_P( x ) ((FTC_Node*)( x )) - - - /* each cache really implements a dynamic hash table to manage its nodes */ - typedef struct FTC_CacheRec_ - { - FTC_Manager manager; - FT_Memory memory; - FTC_Cache_Class clazz; - - FT_UInt cache_index; /* in manager's table */ - FT_Pointer cache_data; /* used by cache node methods */ - - FT_UFast nodes; - FT_UFast size; - FTC_Node* buckets; - - } FTC_CacheRec; - - -#define FTC_CACHE( x ) ((FTC_Cache)( x )) -#define FTC_CACHE_P( x ) ((FTC_Cache*)( x )) - - - /* initialize a given cache */ - typedef FT_Error - (*FTC_Cache_InitFunc)( FTC_Cache cache ); - - /* finalize a given cache */ - typedef void - (*FTC_Cache_DoneFunc)( FTC_Cache cache ); - - /* initialize a new cache node */ - typedef FT_Error - (*FTC_Node_InitFunc)( FTC_Node node, - FT_Pointer type, - FTC_Cache cache ); - - /* compute the weight of a given cache node */ - typedef FT_ULong - (*FTC_Node_WeightFunc)( FTC_Node node, - FTC_Cache cache ); - - /* compare a node to a given key pair */ - typedef FT_Bool - (*FTC_Node_CompareFunc)( FTC_Node node, - FT_Pointer key, - FTC_Cache cache ); - - /* finalize a given cache node */ - typedef void - (*FTC_Node_DoneFunc)( FTC_Node node, - FTC_Cache cache ); - - - typedef struct FTC_Cache_ClassRec_ - { - FT_UInt cache_size; - FTC_Cache_InitFunc cache_init; - FTC_Cache_DoneFunc cache_done; - - FT_UInt node_size; - FTC_Node_InitFunc node_init; - FTC_Node_WeightFunc node_weight; - FTC_Node_CompareFunc node_compare; - FTC_Node_DoneFunc node_done; - - } FTC_Cache_ClassRec; - - /* */ - -#define FTC_CACHE_RESIZE_TEST( c ) \ - ( (c)->nodes*3 < (c)->size || \ - (c)->size*3 < (c)->nodes ) - - /* this must be used internally for the moment */ FT_EXPORT( FT_Error ) FTC_Manager_Register_Cache( FTC_Manager manager, @@ -291,37 +204,16 @@ FT_BEGIN_HEADER FTC_Cache *acache ); - /* can be used directly as FTC_Cache_DoneFunc(), or called by custom */ - /* cache finalizers */ - FT_EXPORT( void ) - ftc_cache_done( FTC_Cache cache ); - - /* initalize the hash table within the cache */ - FT_EXPORT( FT_Error ) - ftc_cache_init( FTC_Cache cache ); - - /* can be used when FTC_CACHE_RESIZE_TEST returns TRUE after a node */ - /* insertion */ - FT_EXPORT( void ) - ftc_cache_resize( FTC_Cache cache ); + /* can be called to increment a node's reference count */ + FT_EXPORT(void) + FTC_Node_Ref( FTC_Node node, + FTC_Manager manager ); - /* can be called when the key's hash value has been computed */ - FT_EXPORT( FT_Error ) - ftc_cache_lookup_node( FTC_Cache cache, - FT_UFast key_hash, - FT_Pointer key, - FTC_Node *anode ); - - /* can be called to increment a node's reference count */ - FT_EXPORT( void ) - ftc_node_ref( FTC_Node node, - FTC_Cache cache ); - - /* can be called to decrement a node's reference count */ - FT_EXPORT( void ) - ftc_node_unref( FTC_Node node, - FTC_Cache cache ); + /* can be called to decrement a node's reference count */ + FT_EXPORT(void) + FTC_Node_Unref( FTC_Node node, + FTC_Manager manager ); /* */ diff --git a/include/freetype/cache/ftcsbits.h b/include/freetype/cache/ftcsbits.h index 1a30846d7..d051b7c71 100644 --- a/include/freetype/cache/ftcsbits.h +++ b/include/freetype/cache/ftcsbits.h @@ -48,20 +48,6 @@ FT_BEGIN_HEADER typedef struct FTC_SBitRec_* FTC_SBit; - /*************************************************************************/ - /* */ - /* */ - /* FTC_SBit_Cache */ - /* */ - /* */ - /* A handle to a small bitmap cache. These are special cache objects */ - /* used to store small glyph bitmaps (and anti-aliased pixmaps) in a */ - /* much more efficient way than the traditional glyph image cache */ - /* implemented by FTC_Image_Cache. */ - /* */ - typedef struct FTC_SBit_CacheRec_* FTC_SBit_Cache; - - /*************************************************************************/ /* */ /* */ @@ -112,6 +98,100 @@ FT_BEGIN_HEADER } FTC_SBitRec; + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBit_Cache */ + /* */ + /* */ + /* A handle to a small bitmap cache. These are special cache objects */ + /* used to store small glyph bitmaps (and anti-aliased pixmaps) in a */ + /* much more efficient way than the traditional glyph image cache */ + /* implemented by FTC_Image_Cache. */ + /* */ + typedef struct FTC_SBitCacheRec_* FTC_SBitCache; + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBit_Cache */ + /* */ + /* */ + /* deprecated. please use @FTC_SBitCache instead */ + /* */ + typedef FTC_SBitCache FTC_SBit_Cache; + + + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBitCache_New */ + /* */ + /* */ + /* Creates a new cache to store small glyph bitmaps. */ + /* */ + /* */ + /* manager :: A handle to the source cache manager. */ + /* */ + /* */ + /* acache :: A handle to the new sbit cache. NULL in case of error. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_New( FTC_Manager manager, + FTC_SBitCache *acache ); + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBitCache_Lookup */ + /* */ + /* */ + /* Looks up a given small glyph bitmap in a given sbit cache and */ + /* "lock" it to prevent its flushing from the cache until needed */ + /* */ + /* */ + /* cache :: A handle to the source sbit cache. */ + /* desc :: A pointer to the glyph image descriptor. */ + /* gindex :: The glyph index. */ + /* */ + /* */ + /* sbit :: A handle to a small bitmap descriptor. */ + /* */ + /* anode :: an opaque cache node pointer that will be used */ + /* to release the sbit once it becomes unuseful. */ + /* can be NULL, in which case this function will */ + /* have the same effect than @FTC_SBit_Cache_Lookup */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* The small bitmap descriptor and its bit buffer are owned by the */ + /* cache and should never be freed by the application. They might */ + /* as well disappear from memory on the next cache lookup, so don't */ + /* treat them as persistent data. */ + /* */ + /* The descriptor's `buffer' field is set to 0 to indicate a missing */ + /* glyph bitmap. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_Lookup( FTC_SBitCache cache, + FTC_ImageDesc* desc, + FT_UInt gindex, + FTC_SBit *sbit, + FTC_Node *anode ); + + + /* */ + + /*************************************************************************/ /* */ /* */ @@ -169,9 +249,6 @@ FT_BEGIN_HEADER FTC_SBit *sbit ); - /* */ - - FT_END_HEADER #endif /* __FTCSBITS_H__ */ diff --git a/include/freetype/cache/ftlru.h b/include/freetype/cache/ftlru.h index d39081418..9d51e571a 100644 --- a/include/freetype/cache/ftlru.h +++ b/include/freetype/cache/ftlru.h @@ -58,14 +58,11 @@ #ifndef __FTLRU_H__ #define __FTLRU_H__ - #include #include FT_FREETYPE_H - FT_BEGIN_HEADER - /* generic list key type */ typedef FT_Pointer FT_LruKey; @@ -75,9 +72,8 @@ FT_BEGIN_HEADER /* list class handle */ typedef const struct FT_LruList_ClassRec_* FT_LruList_Class; - /* a list node handle */ - typedef struct FT_LruNodeRec_* FT_LruNode; - + /* an list node handle */ + typedef struct FT_LruNodeRec_* FT_LruNode; /* the list node structure */ typedef struct FT_LruNodeRec_ @@ -96,25 +92,25 @@ FT_BEGIN_HEADER FT_LruNode nodes; FT_UInt max_nodes; FT_UInt num_nodes; - FT_Pointer user_data; + FT_Pointer data; } FT_LruListRec; /* initialize a list list */ typedef FT_Error (*FT_LruList_InitFunc)( FT_LruList list ); - - /* finalize a list list */ + + /* finalize a list list */ typedef void (*FT_LruList_DoneFunc)( FT_LruList list ); /* this method is used to initialize a new list element node */ typedef FT_Error (*FT_LruNode_InitFunc)( FT_LruNode node, FT_LruKey key, - FT_LruList list ); + FT_Pointer data ); /* this method is used to finalize a given list element node */ typedef void (*FT_LruNode_DoneFunc)( FT_LruNode node, - FT_LruList list ); + FT_Pointer data ); /* If defined, this method is called when the list if full */ /* during the lookup process -- it is used to change the contents */ @@ -122,14 +118,14 @@ FT_BEGIN_HEADER /* then `init_element()'. Set it to 0 for default behaviour. */ typedef FT_Error (*FT_LruNode_FlushFunc)( FT_LruNode node, FT_LruKey new_key, - FT_LruList list ); + FT_Pointer data ); /* If defined, this method is used to compare a list element node */ /* with a given key during a lookup. If set to 0, the `key' */ /* fields will be directly compared instead. */ typedef FT_Bool (*FT_LruNode_CompareFunc)( FT_LruNode node, FT_LruKey key, - FT_LruList list ); + FT_Pointer data ); /* A selector is used to indicate whether a given list element node */ /* is part of a selection for FT_LruList_Remove_Selection(). The */ @@ -137,7 +133,7 @@ FT_BEGIN_HEADER /* node is part of it. */ typedef FT_Bool (*FT_LruNode_SelectFunc)( FT_LruNode node, FT_Pointer data, - FT_LruList list ); + FT_Pointer list_data ); /* LRU class */ typedef struct FT_LruList_ClassRec_ @@ -145,7 +141,7 @@ FT_BEGIN_HEADER FT_UInt list_size; FT_LruList_InitFunc list_init; /* optional */ FT_LruList_DoneFunc list_done; /* optional */ - + FT_UInt node_size; FT_LruNode_InitFunc node_init; /* MANDATORY */ FT_LruNode_DoneFunc node_done; /* optional */ @@ -190,7 +186,7 @@ FT_BEGIN_HEADER FT_Pointer select_data ); /* */ - + FT_END_HEADER #endif /* __FTLRU_H__ */ diff --git a/include/freetype/config/ftheader.h b/include/freetype/config/ftheader.h index b4ec98b1f..bd64ce41e 100644 --- a/include/freetype/config/ftheader.h +++ b/include/freetype/config/ftheader.h @@ -467,7 +467,7 @@ #define FT_CACHE_INTERNAL_LRU_H #define FT_CACHE_INTERNAL_GLYPH_H -#define FT_CACHE_INTERNAL_CHUNK_H +#define FT_CACHE_INTERNAL_CACHE_H /* now include internal headers definitions from */ diff --git a/include/freetype/ftcache.h b/include/freetype/ftcache.h index d28b21da1..b05910202 100644 --- a/include/freetype/ftcache.h +++ b/include/freetype/ftcache.h @@ -57,6 +57,37 @@ FT_BEGIN_HEADER /* This section describes the FreeType 2 cache sub-system which is */ /* stile in beta. */ /* */ + /* */ + /* FTC_Manager */ + /* FTC_FaceID */ + /* FTC_Face_Requester */ + /* */ + /* FTC_Manager_New */ + /* FTC_Manager_Lookup_Face */ + /* FTC_Manager_Lookup_Size */ + /* */ + /* FTC_Node */ + /* FTC_Node_Unref */ + /* */ + /* FTC_Font */ + /* FTC_ImageDesc */ + /* FTC_ImageCache */ + /* FTC_ImageCache_New */ + /* FTC_ImageCache_Lookup */ + /* */ + /* FTC_SBit */ + /* FTC_SBitCache */ + /* FTC_SBitCache_New */ + /* FTC_SBitCache_Lookup */ + /* */ + /* */ + /* FTC_Image_Desc */ + /* FTC_Image_Cache */ + /* FTC_Image_Cache_Lookup */ + /* */ + /* FTC_SBit_Cache */ + /* FTC_Sbit_Cache_Lookup */ + /* */ /*************************************************************************/ @@ -157,7 +188,6 @@ FT_BEGIN_HEADER ((f)->pix_width << 8) ^ \ ((f)->pix_height) ) - /*************************************************************************/ /* */ /* */ @@ -192,6 +222,26 @@ FT_BEGIN_HEADER typedef struct FTC_ManagerRec_* FTC_Manager; + /*************************************************************************/ + /* */ + /* */ + /* FTC_Node */ + /* */ + /* */ + /* an opaque handle to a cache node object. Each cache node is */ + /* reference-counted. A node with a count of 0 might be flushed */ + /* out of a full cache whenever a lookup request is performed */ + /* */ + /* when you lookup nodes, you have the ability to "acquire" them, */ + /* i.e. increment their reference count. This will prevent the node */ + /* from being flushed out of the cache until you explicitely */ + /* "release" it (see @FTC_Node_Release) */ + /* */ + /* see @FTC_BitsetCache_Lookup and @FTC_ImageCache_Lookup */ + /* */ + typedef struct FTC_NodeRec_* FTC_Node; + + /*************************************************************************/ /* */ /* */ @@ -349,6 +399,24 @@ FT_BEGIN_HEADER FT_Face *aface, FT_Size *asize ); + /*************************************************************************/ + /* */ + /* */ + /* FTC_Node_Unref */ + /* */ + /* */ + /* decrement a cache node's internal reference count. when the count */ + /* reaches 0, it is not destroyed but becomes eligible for subsequent */ + /* cache flushes.. */ + /* */ + /* */ + /* node :: cache node handle */ + /* manager :: cache manager handle */ + /* */ + FT_EXPORT( void ) + FTC_Node_Unref( FTC_Node node, + FTC_Manager manager ); + /* */ diff --git a/src/autohint/ahhint.c b/src/autohint/ahhint.c index b6b2c7870..eb9e13bcb 100644 --- a/src/autohint/ahhint.c +++ b/src/autohint/ahhint.c @@ -384,8 +384,8 @@ ah_debug_disable_horz = no_horz_edges; ah_debug_disable_vert = no_vert_edges; #else - UNUSED( no_horz_edges ); - UNUSED( no_vert_edges ); + FT_UNUSED(no_horz_edges); + FT_UNUSED(no_vert_edges); #endif /* AH_Interpolate_Blue_Edges( hinter ); -- doesn't seem to help */ /* reduce the problem of the disappearing eye in the `e' of Times... */ diff --git a/src/base/ftdbgmem.c b/src/base/ftdbgmem.c index 7f50bd621..8939b1359 100644 --- a/src/base/ftdbgmem.c +++ b/src/base/ftdbgmem.c @@ -662,8 +662,8 @@ #else /* !FT_DEBUG_MEMORY */ - - /* ANSI C doesn't like empty source files */ + + /* ansi C doesn't like empty source files */ extern const FT_Byte _debug_mem_dummy = 0; #endif /* !FT_DEBUG_MEMORY */ diff --git a/src/cache/Jamfile b/src/cache/Jamfile index 1cbdc776f..a4905b156 100644 --- a/src/cache/Jamfile +++ b/src/cache/Jamfile @@ -16,7 +16,7 @@ HDRMACRO [ FT2_SubDir include ftcache.h ] ; if $(FT2_MULTI) { - _sources = ftlru ftcmanag ftcglyph ftcchunk ftcsbits ftcimage ; + _sources = ftlru ftcmanag ftccache ftcglyph ftcsbits ftcimage ; } else { diff --git a/src/cache/ftcache.c b/src/cache/ftcache.c index 63f7f8e78..a80348db4 100644 --- a/src/cache/ftcache.c +++ b/src/cache/ftcache.c @@ -21,8 +21,8 @@ #include #include "ftlru.c" #include "ftcmanag.c" +#include "ftccache.c" #include "ftcglyph.c" -#include "ftcchunk.c" #include "ftcimage.c" #include "ftcsbits.c" diff --git a/src/cache/ftcglyph.c b/src/cache/ftcglyph.c index c2effddfd..8be466fbd 100644 --- a/src/cache/ftcglyph.c +++ b/src/cache/ftcglyph.c @@ -27,143 +27,96 @@ #include "ftcerror.h" - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GLYPH NODES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ -#define FTC_GSET_HASH( gset, gindex ) \ - ( (FT_UFast)( ( (gset)->hash << 16 ) | ( (gindex) & 0xFFFF ) ) ) - - - /* create a new glyph node, setting its cache index and ref count */ + /* create a new chunk node, setting its cache index and ref count */ FT_EXPORT_DEF( void ) - ftc_glyph_node_init( FTC_GlyphNode gnode, - FT_UInt gindex, - FTC_GlyphSet gset ) + ftc_glyph_node_init( FTC_GlyphNode gnode, + FT_UInt gindex, + FTC_GlyphFamily gfam ) { - gnode->gset = gset; - gnode->node.hash = FTC_GSET_HASH( gset, gindex ); - gset->num_glyphs++; + FT_UInt len; + FT_UInt start = FTC_GLYPH_FAMILY_START(gfam,gindex); + + + gnode->node.fam_index = (FT_UShort) gfam->family.fam_index; + gnode->node.hash = FTC_GLYPH_FAMILY_HASH(gfam,gindex); + gnode->item_start = (FT_UShort) start; + + len = gfam->item_total - start; + if ( len > gfam->item_count ) + len = gfam->item_count; + + gnode->item_count = (FT_UShort) len; + gfam->family.num_nodes++; } - /* Important: This function is called from the cache manager to */ - /* destroy a given cache node during `cache compression'. The */ - /* second argument is always `cache.cache_data'. Thus be */ - /* certain that the function FTC_Glyph_Cache_New() does indeed */ - /* set its `cache_data' field correctly, otherwise bad things */ - /* will happen! */ - FT_EXPORT_DEF( void ) - ftc_glyph_node_done( FTC_GlyphNode gnode ) + ftc_glyph_node_done( FTC_GlyphNode gnode, + FTC_Cache cache ) { - FTC_GlyphSet gset = gnode->gset; - + /* finalize the node */ + gnode->item_count = 0; + gnode->item_start = 0; - if ( --gset->num_glyphs <= 0 ) - FT_LruList_Remove( gset->gcache->gset_lru, (FT_LruNode)gset ); + ftc_node_done( FTC_NODE(gnode), cache ); + } + + + FT_EXPORT_DEF( FT_Bool ) + ftc_glyph_node_compare( FTC_GlyphNode gnode, + FTC_GlyphQuery gquery ) + { + FT_UInt fam_index = (FT_UInt) FTC_NODE(gnode)->fam_index; + FT_UInt start = (FT_UInt) gnode->item_start; + FT_UInt count = (FT_UInt) gnode->item_count; + + return FT_BOOL( (FT_UInt)(gquery->gindex - start) < count && + gquery->query.family->fam_index == fam_index ); } /*************************************************************************/ /*************************************************************************/ /***** *****/ - /***** GLYPH SETS *****/ + /***** CHUNK SETS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_EXPORT_DEF( FT_Error ) - ftc_glyph_set_init( FTC_GlyphSet gset, - FT_LruList lru ) - { - FTC_GlyphCache gcache = lru->user_data; - - - gset->gcache = gcache; - gset->num_glyphs = 0; - - return 0; - } - - - FT_EXPORT_DEF( void ) - ftc_glyph_set_done( FTC_GlyphSet gset ) - { - /* for now, nothing to be done here */ - FT_UNUSED( gset ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GLYPH CACHES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_EXPORT_DEF( void ) - ftc_glyph_cache_done( FTC_GlyphCache gcache ) - { - /* remove all nodes in the cache */ - ftc_cache_done( &gcache->cache ); - - /* simply delete all remaining glyph sets */ - if ( gcache->gset_lru ) - { - FT_LruList_Destroy( gcache->gset_lru ); - gcache->gset_lru = NULL; - } - } - - - FT_EXPORT_DEF( FT_Error ) - ftc_glyph_cache_init( FTC_GlyphCache gcache, - FT_LruList_Class gset_class ) + ftc_glyph_family_init( FTC_GlyphFamily gfam, + FT_UInt32 hash, + FT_UInt item_count, + FT_UInt item_total, + FTC_GlyphQuery gquery, + FTC_Cache cache ) { FT_Error error; - error = ftc_cache_init( FTC_CACHE( gcache ) ); - if ( error ) - goto Exit; - - error = FT_LruList_New( gset_class, 0, gcache, - gcache->cache.memory, - &gcache->gset_lru ); - Exit: - return error; - } - - - FT_EXPORT_DEF( FT_Error ) - ftc_glyph_cache_lookup( FTC_GlyphCache gcache, - FTC_GlyphQuery query, - FTC_GlyphNode *anode ) - { - FT_LruNode node; - FT_Error error; - - - error = FT_LruList_Lookup( gcache->gset_lru, query, &node ); - if ( !error ) + error = ftc_family_init( FTC_FAMILY(gfam), FTC_QUERY(gquery), cache ); + if (!error) { - FTC_GlyphSet gset = (FTC_GlyphSet)node; - FT_UFast hash = FTC_GSET_HASH( gset, query->gindex ); - - error = ftc_cache_lookup_node( FTC_CACHE( gcache ), hash, query, - FTC_NODE_P( anode ) ); + gfam->hash = hash; + gfam->item_total = item_total; + gfam->item_count = item_count; + + FTC_GLYPH_FAMILY_FOUND(gfam,gquery); } + return error; } + FT_EXPORT_DEF( void ) + ftc_glyph_family_done( FTC_GlyphFamily gfam ) + { + ftc_family_done( FTC_FAMILY(gfam) ); + } + + + /* END */ diff --git a/src/cache/ftcimage.c b/src/cache/ftcimage.c index 6a2b4d1b7..2d5cfcca8 100644 --- a/src/cache/ftcimage.c +++ b/src/cache/ftcimage.c @@ -41,26 +41,30 @@ #define FTC_IMAGE_NODE_GINDEX( x ) FTC_GLYPH_NODE_GINDEX( x ) - /* the glyph image set type */ - typedef struct FTC_ImageSetRec_ - { - FTC_GlyphSetRec gset; - FTC_Image_Desc description; - - } FTC_ImageSetRec, *FTC_ImageSet; - - -#define FTC_IMAGE_SET( x ) ((FTC_ImageSet)( x )) -#define FTC_IMAGE_SET_MEMORY( x ) FTC_GLYPH_SET_MEMORY( &(x)->gset ) - - + /* the glyph image query */ typedef struct FTC_ImageQueryRec_ { - FTC_GlyphQueryRec glyph; - FTC_Image_Desc desc; + FTC_GlyphQueryRec gquery; + FTC_ImageDesc desc; } FTC_ImageQueryRec, *FTC_ImageQuery; +#define FTC_IMAGE_QUERY(x) ((FTC_ImageQuery)(x)) + + + + /* the glyph image set type */ + typedef struct FTC_ImageFamilyRec_ + { + FTC_GlyphFamilyRec gfam; + FTC_ImageDesc desc; + + } FTC_ImageFamilyRec, *FTC_ImageFamily; + + +#define FTC_IMAGE_FAMILY( x ) ((FTC_ImageFamily)( x )) +#define FTC_IMAGE_FAMILY_MEMORY( x ) FTC_GLYPH_FAMILY_MEMORY( &(x)->gfam ) + /*************************************************************************/ /*************************************************************************/ @@ -73,65 +77,70 @@ /* finalize a given glyph image node */ FT_CALLBACK_DEF( void ) - ftc_image_node_done( FTC_ImageNode inode ) + ftc_image_node_done( FTC_ImageNode inode, + FTC_Cache cache ) { if ( inode->glyph ) { FT_Done_Glyph( inode->glyph ); inode->glyph = NULL; } + ftc_glyph_node_done( FTC_GLYPH_NODE(inode), cache ); } + /* initialize a new glyph image node */ FT_CALLBACK_DEF( FT_Error ) ftc_image_node_init( FTC_ImageNode inode, - FTC_GlyphQuery query ) + FTC_GlyphQuery gquery, + FTC_Cache cache ) { - FTC_ImageSet iset = FTC_IMAGE_SET( query->gset ); - FT_Error error; - FT_Face face; - FT_Size size; + FTC_ImageFamily ifam = FTC_IMAGE_FAMILY( gquery->query.family ); + FT_Error error; + FT_Face face; + FT_Size size; /* initialize its inner fields */ - ftc_glyph_node_init( FTC_GLYPH_NODE( inode ), - query->gindex, query->gset ); + ftc_glyph_node_init( FTC_GLYPH_NODE(inode), + gquery->gindex, + FTC_GLYPH_FAMILY(ifam) ); /* we will now load the glyph image */ - error = FTC_Manager_Lookup_Size( iset->gset.gcache->cache.manager, - &iset->description.font, + error = FTC_Manager_Lookup_Size( FTC_FAMILY(ifam)->cache->manager, + &ifam->desc.font, &face, &size ); if ( !error ) { FT_UInt gindex = FTC_GLYPH_NODE_GINDEX(inode); FT_UInt load_flags = FT_LOAD_DEFAULT; - FT_UInt image_type = iset->description.image_type; + FT_UInt type = ifam->desc.type; - if ( FTC_IMAGE_FORMAT( image_type ) == ftc_image_format_bitmap ) + if ( FTC_IMAGE_FORMAT( type ) == ftc_image_format_bitmap ) { load_flags |= FT_LOAD_RENDER; - if ( image_type & ftc_image_flag_monochrome ) + if ( type & ftc_image_flag_monochrome ) load_flags |= FT_LOAD_MONOCHROME; /* disable embedded bitmaps loading if necessary */ - if ( image_type & ftc_image_flag_no_sbits ) + if ( type & ftc_image_flag_no_sbits ) load_flags |= FT_LOAD_NO_BITMAP; } - else if ( FTC_IMAGE_FORMAT( image_type ) == ftc_image_format_outline ) + else if ( FTC_IMAGE_FORMAT( type ) == ftc_image_format_outline ) { /* disable embedded bitmaps loading */ load_flags |= FT_LOAD_NO_BITMAP; - if ( image_type & ftc_image_flag_unscaled ) + if ( type & ftc_image_flag_unscaled ) load_flags |= FT_LOAD_NO_SCALE; } - if ( image_type & ftc_image_flag_unhinted ) + if ( type & ftc_image_flag_unhinted ) load_flags |= FT_LOAD_NO_HINTING; - if ( image_type & ftc_image_flag_autohinted ) + if ( type & ftc_image_flag_autohinted ) load_flags |= FT_LOAD_FORCE_AUTOHINT; error = FT_Load_Glyph( face, gindex, load_flags ); @@ -157,7 +166,7 @@ } /* in case of error */ - ftc_glyph_node_done( FTC_GLYPH_NODE( inode ) ); + ftc_glyph_node_done( FTC_GLYPH_NODE(inode), cache ); Exit: return error; @@ -206,19 +215,6 @@ } - /* this function assumes that the desired node's glyph set has been */ - /* set by a previous call to ftc_image_set_compare() */ - /* */ - FT_CALLBACK_DEF( FT_Bool ) - ftc_image_node_compare( FTC_ImageNode inode, - FTC_ImageQuery iquery ) - { - /* only if same glyph index and image set description */ - return FT_BOOL( iquery->glyph.gindex == FTC_IMAGE_NODE_GINDEX( inode ) && - iquery->glyph.gset == inode->gnode.gset ); - } - - /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -229,53 +225,51 @@ FT_CALLBACK_DEF( FT_Error ) - ftc_image_set_init( FTC_ImageSet iset, - FTC_ImageQuery query, - FT_LruList lru ) + ftc_image_family_init( FTC_ImageFamily ifam, + FTC_ImageQuery iquery, + FTC_Cache cache ) { - ftc_glyph_set_init( &iset->gset, lru ); - iset->description = query->desc; + FTC_Manager manager = cache->manager; + FT_Error error; + FT_Face face; - /* now compute hash from description -- this is _very_ important */ - iset->gset.hash = FTC_IMAGE_DESC_HASH( &query->desc ); - query->glyph.gset = FTC_GLYPH_SET( iset ); - return 0; + ifam->desc = iquery->desc; + + /* we need to compute "iquery.item_total" now */ + error = FTC_Manager_Lookup_Face( manager, + iquery->desc.font.face_id, + &face ); + if ( !error ) + { + error = ftc_glyph_family_init( FTC_GLYPH_FAMILY(ifam), + FTC_IMAGE_DESC_HASH( &ifam->desc ), + 1, + face->num_glyphs, + FTC_GLYPH_QUERY(iquery), + cache ); + } + + return error; } FT_CALLBACK_DEF( FT_Bool ) - ftc_image_set_compare( FTC_ImageSet iset, - FTC_ImageQuery iquery ) + ftc_image_family_compare( FTC_ImageFamily ifam, + FTC_ImageQuery iquery ) { FT_Bool result; - /* we must set iquery.glyph.gset for faster glyph node comparisons */ - result = FT_BOOL( FTC_IMAGE_DESC_COMPARE( &iset->description, - &iquery->desc ) ); + /* we must set iquery.glyph.gfam for faster glyph node comparisons */ + result = FT_BOOL( FTC_IMAGE_DESC_COMPARE( &ifam->desc, &iquery->desc ) ); if ( result ) - iquery->glyph.gset = &iset->gset; + FTC_GLYPH_FAMILY_FOUND(ifam,iquery); return result; } - FT_CALLBACK_TABLE_DEF - const FT_LruList_ClassRec ftc_image_set_class = - { - sizeof ( FT_LruListRec ), - (FT_LruList_InitFunc) NULL, - (FT_LruList_DoneFunc) NULL, - - sizeof ( FTC_ImageSetRec ), - (FT_LruNode_InitFunc) ftc_image_set_init, - (FT_LruNode_DoneFunc) ftc_glyph_set_init, - (FT_LruNode_FlushFunc) NULL, - (FT_LruNode_CompareFunc)ftc_image_set_compare - }; - - /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -285,34 +279,33 @@ /*************************************************************************/ - FT_CALLBACK_DEF( FT_Error ) - ftc_image_cache_init( FTC_Image_Cache cache ) - { - return ftc_glyph_cache_init( (FTC_GlyphCache)cache, - &ftc_image_set_class ); - } - FT_CALLBACK_TABLE_DEF const FTC_Cache_ClassRec ftc_image_cache_class = { - sizeof ( FTC_GlyphCacheRec ), - (FTC_Cache_InitFunc) ftc_image_cache_init, - (FTC_Cache_DoneFunc) ftc_glyph_cache_done, + sizeof( FTC_CacheRec ), + (FTC_Cache_InitFunc) ftc_cache_init, + (FTC_Cache_ClearFunc) ftc_cache_clear, + (FTC_Cache_DoneFunc) ftc_cache_done, - sizeof ( FTC_ImageNodeRec ), - (FTC_Node_InitFunc) ftc_image_node_init, - (FTC_Node_WeightFunc) ftc_image_node_weight, - (FTC_Node_CompareFunc)ftc_image_node_compare, - (FTC_Node_DoneFunc) ftc_image_node_done + sizeof( FTC_ImageFamilyRec ), + (FTC_Family_InitFunc) ftc_image_family_init, + (FTC_Family_CompareFunc) ftc_image_family_compare, + (FTC_Family_DoneFunc) ftc_glyph_family_done, + + sizeof( FTC_ImageNodeRec ), + (FTC_Node_InitFunc) ftc_image_node_init, + (FTC_Node_WeightFunc) ftc_image_node_weight, + (FTC_Node_CompareFunc) ftc_glyph_node_compare, + (FTC_Node_DoneFunc) ftc_image_node_done }; /* documentation is in ftcimage.h */ FT_EXPORT_DEF( FT_Error ) - FTC_Image_Cache_New( FTC_Manager manager, - FTC_Image_Cache *acache ) + FTC_ImageCache_New( FTC_Manager manager, + FTC_ImageCache *acache ) { return FTC_Manager_Register_Cache( manager, @@ -324,37 +317,37 @@ /* documentation is in ftcimage.h */ FT_EXPORT_DEF( FT_Error ) - FTC_Image_Cache_Acquire( FTC_Image_Cache cache, - FTC_Image_Desc* desc, - FT_UInt gindex, - FT_Glyph *aglyph, - FTC_Node *anode ) + FTC_ImageCache_Lookup( FTC_ImageCache cache, + FTC_ImageDesc* desc, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ) { - FTC_ImageQueryRec query; + FTC_ImageQueryRec iquery; FTC_ImageNode node; FT_Error error; - /* some argument checks are delayed to ftc_glyph_cache_lookup() */ - if ( !cache || !desc || !aglyph ) - return FTC_Err_Invalid_Argument; + /* some argument checks are delayed to ftc_glyph_cache_lookup */ + if ( aglyph ) + *aglyph = NULL; *aglyph = NULL; if ( anode ) *anode = NULL; - query.glyph.gindex = gindex; - query.glyph.gset = NULL; - query.desc = *desc; - error = ftc_glyph_cache_lookup( FTC_GLYPH_CACHE( cache ), - &query.glyph, - (FTC_GlyphNode*)&node ); + iquery.gquery.gindex = gindex; + iquery.desc = *desc; + + error = ftc_cache_lookup( FTC_CACHE(cache), + FTC_QUERY(&iquery), + (FTC_Node*) &node ); if ( !error ) { *aglyph = node->glyph; - if ( anode ) + if (anode) { *anode = (FTC_Node)node; FTC_NODE(node)->ref_count++; @@ -365,11 +358,14 @@ } - FT_EXPORT_DEF( void ) - FTC_Image_Cache_Release( FTC_Image_Cache icache, - FTC_Node node ) + + /* backwards-compatibility functions */ + + FT_EXPORT_DEF( FT_Error ) + FTC_Image_Cache_New( FTC_Manager manager, + FTC_Image_Cache *acache ) { - ftc_node_unref( node, FTC_CACHE( icache ) ); + return FTC_ImageCache_New( manager, (FTC_ImageCache*)acache ); } @@ -379,7 +375,19 @@ FT_UInt gindex, FT_Glyph *aglyph ) { - return FTC_Image_Cache_Acquire( icache, desc, gindex, aglyph, NULL ); + FTC_ImageDesc desc0; + + if ( !desc ) + return FT_Err_Invalid_Argument; + + desc0.font = desc->font; + desc0.type = (FT_UInt32) desc->image_type; + + return FTC_ImageCache_Lookup( (FTC_ImageCache)icache, + &desc0, + gindex, + aglyph, + NULL ); } diff --git a/src/cache/ftcmanag.c b/src/cache/ftcmanag.c index 03f2303f1..8e834d174 100644 --- a/src/cache/ftcmanag.c +++ b/src/cache/ftcmanag.c @@ -22,7 +22,6 @@ #include FT_CACHE_INTERNAL_LRU_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H -#include FT_LIST_H #include FT_SIZES_H #include "ftcerror.h" @@ -63,12 +62,11 @@ FT_CALLBACK_DEF( FT_Error ) - ftc_face_node_init( FTC_FaceNode node, - FTC_FaceID face_id, - FT_LruList list ) + ftc_face_node_init( FTC_FaceNode node, + FTC_FaceID face_id, + FTC_Manager manager ) { - FTC_Manager manager = FTC_LRU_GET_MANAGER( list ); - FT_Error error; + FT_Error error; error = manager->request_face( face_id, @@ -97,10 +95,9 @@ FT_CALLBACK_DEF( void ) ftc_face_node_done( FTC_FaceNode node, - FT_LruList list ) + FTC_Manager manager ) { - FTC_Manager manager = FTC_LRU_GET_MANAGER( list ); - FT_Face face = node->face; + FT_Face face = node->face; /* we must begin by removing all sizes for the target face */ @@ -130,6 +127,36 @@ }; + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_Manager_Lookup_Face( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ) + { + FT_Error error; + FTC_FaceNode node; + + + if ( aface == NULL ) + return FTC_Err_Bad_Argument; + + *aface = NULL; + + if ( !manager ) + return FTC_Err_Invalid_Cache_Handle; + + error = FT_LruList_Lookup( manager->faces_list, + (FT_LruKey)face_id, + (FT_LruNode*)&node ); + if ( !error ) + *aface = node->face; + + return error; + } + + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -242,6 +269,169 @@ }; + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_Manager_Lookup_Size( FTC_Manager manager, + FTC_Font font, + FT_Face *aface, + FT_Size *asize ) + { + FT_Error error; + + + /* check for valid `manager' delayed to FTC_Manager_Lookup_Face() */ + if ( aface ) + *aface = 0; + + if ( asize ) + *asize = 0; + + error = FTC_Manager_Lookup_Face( manager, font->face_id, aface ); + if ( !error ) + { + FTC_SizeQueryRec query; + FTC_SizeNode node; + + + query.face = *aface; + query.width = font->pix_width; + query.height = font->pix_height; + + error = FT_LruList_Lookup( manager->sizes_list, + (FT_LruKey)&query, + (FT_LruNode*)&node ); + if ( !error ) + { + /* select the size as the current one for this face */ + FT_Activate_Size( node->size ); + + if ( asize ) + *asize = node->size; + } + } + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SET TABLE MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + ftc_family_table_init( FTC_FamilyTable table ) + { + table->count = 0; + table->size = 0; + table->entries = NULL; + table->free = FTC_FAMILY_ENTRY_NONE; + } + + + static void + ftc_family_table_done( FTC_FamilyTable table, + FT_Memory memory ) + { + FREE( table->entries ); + table->free = 0; + table->count = 0; + table->size = 0; + } + + + FT_LOCAL_DEF FT_Error + ftc_family_table_alloc( FTC_FamilyTable table, + FT_Memory memory, + FTC_FamilyEntry *aentry ) + { + FTC_FamilyEntry entry; + FT_Error error = 0; + + /* re-allocate table size when needed */ + if ( table->free == FTC_FAMILY_ENTRY_NONE && table->count >= table->size ) + { + FT_UInt old_size = table->size; + FT_UInt new_size, index; + + if ( old_size == 0 ) + new_size = 8; + else + { + new_size = old_size*2; + + /* check for (unlikely) overflow */ + if ( new_size < old_size ) + new_size = 65534; + } + + if ( REALLOC_ARRAY( table->entries, old_size, new_size, FTC_FamilyEntryRec ) ) + return error; + + table->size = new_size; + + entry = table->entries + old_size; + table->free = old_size; + + for ( index = old_size; index+1 < new_size; index++, entry++ ) + { + entry->link = index+1; + entry->index = index; + } + + entry->link = FTC_FAMILY_ENTRY_NONE; + entry->index = index; + } + + if ( table->free != FTC_FAMILY_ENTRY_NONE ) + { + entry = table->entries + table->free; + table->free = entry->link; + } + else if ( table->count < table->size ) + { + entry = table->entries + table->count++; + } + else + { + FT_ERROR(( "FreeType.cache.alloc_set: internal bug !!" )); + return FT_Err_Invalid_Argument; + } + + entry->link = FTC_FAMILY_ENTRY_NONE; + table->count++; + + *aentry = entry; + return error; + } + + + FT_LOCAL_DEF void + ftc_family_table_free( FTC_FamilyTable table, + FT_UInt index ) + { + /* simply add it to the linked list of free entries */ + if ( index < table->count ) + { + FTC_FamilyEntry entry = table->entries + index; + + if ( entry->link != FTC_FAMILY_ENTRY_NONE ) + FT_ERROR(( "FreeType.cache.set_free: internal bug !!\n" )); + else + { + entry->link = table->free; + table->free = entry->index; + table->count--; + } + } + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -307,6 +497,8 @@ manager->request_face = requester; manager->request_data = req_data; + ftc_family_table_init( &manager->families ); + *amanager = manager; Exit: @@ -348,7 +540,10 @@ manager->caches[index] = 0; } } - + + /* discard families table */ + ftc_family_table_done( &manager->families, memory ); + /* discard faces and sizes */ FT_LruList_Destroy( manager->faces_list ); manager->faces_list = 0; @@ -374,251 +569,10 @@ } - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_Manager_Lookup_Face( FTC_Manager manager, - FTC_FaceID face_id, - FT_Face *aface ) - { - FT_Error error; - FTC_FaceNode node; - - - if ( aface == NULL ) - return FTC_Err_Bad_Argument; - - *aface = NULL; - - if ( !manager ) - return FTC_Err_Invalid_Cache_Handle; - - error = FT_LruList_Lookup( manager->faces_list, - (FT_LruKey)face_id, - (FT_LruNode*)&node ); - if ( !error ) - *aface = node->face; - - return error; - } - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_Manager_Lookup_Size( FTC_Manager manager, - FTC_Font font, - FT_Face *aface, - FT_Size *asize ) - { - FT_Error error; - - - /* check for valid `manager' delayed to FTC_Manager_Lookup_Face() */ - if ( aface ) - *aface = 0; - - if ( asize ) - *asize = 0; - - error = FTC_Manager_Lookup_Face( manager, font->face_id, aface ); - if ( !error ) - { - FTC_SizeQueryRec query; - FTC_SizeNode node; - - - query.face = *aface; - query.width = font->pix_width; - query.height = font->pix_height; - - error = FT_LruList_Lookup( manager->sizes_list, - (FT_LruKey)&query, - (FT_LruNode*)&node ); - if ( !error ) - { - /* select the size as the current one for this face */ - FT_Activate_Size( node->size ); - - if ( asize ) - *asize = node->size; - } - } - - return error; - } - - - /* add a new node to the head of the manager's circular MRU list */ - static void - ftc_node_mru_link( FTC_Node node, - FTC_Manager manager ) - { - FTC_Node first = manager->nodes_list; - - - if ( first ) - { - node->mru_prev = first->mru_prev; - node->mru_next = first; - - first->mru_prev->mru_next = node; - first->mru_prev = node; - } - else - { - node->mru_next = node; - node->mru_prev = node; - } - - manager->nodes_list = node; - manager->num_nodes++; - } - - - /* remove a node from the manager's MRU list */ - static void - ftc_node_mru_unlink( FTC_Node node, - FTC_Manager manager ) - { - FTC_Node prev = node->mru_prev; - FTC_Node next = node->mru_next; - FTC_Node first = manager->nodes_list; - - - prev->mru_next = next; - next->mru_prev = prev; - - if ( node->mru_next == first ) - { - /* this is the last node in the list; update its head pointer */ - if ( node == first ) - manager->nodes_list = NULL; - else - first->mru_prev = prev; - } - - node->mru_next = NULL; - node->mru_prev = NULL; - manager->num_nodes--; - } - - - /* move a node to the head of the manager's MRU list */ - static void - ftc_node_mru_up( FTC_Node node, - FTC_Manager manager ) - { - FTC_Node first = manager->nodes_list; - - - if ( node != first ) - { - ftc_node_mru_unlink( node, manager ); - ftc_node_mru_link( node, manager ); - } - } - - - /* remove a node from its cache's hash table */ - static void - ftc_node_hash_unlink( FTC_Node node, - FTC_Cache cache ) - { - FTC_Node *pnode = cache->buckets + ( node->hash % cache->size ); - - - for (;;) - { - if ( *pnode == NULL ) - { - FT_ERROR(( "FreeType.cache.hash_unlink: unknown node!\n" )); - return; - } - - if ( *pnode == node ) - { - *pnode = node->link; - node->link = NULL; - - cache->nodes--; - return; - } - - pnode = &(*pnode)->link; - } - } - - - /* add a node to the "top" of its cache's hash table */ - static void - ftc_node_hash_link( FTC_Node node, - FTC_Cache cache ) - { - FTC_Node *pnode = cache->buckets + ( node->hash % cache->size ); - - - node->link = *pnode; - *pnode = node; - - cache->nodes++; - } - - - /* remove a node from the cache manager */ - static void - ftc_node_destroy( FTC_Node node, - FTC_Manager manager ) - { - FT_Memory memory = manager->library->memory; - FTC_Cache cache; - FTC_Cache_Class clazz; #ifdef FT_DEBUG_ERROR - /* find node's cache */ - if ( node->cache_index >= FTC_MAX_CACHES ) - { - FT_ERROR(( "FreeType.cache.node_destroy: invalid node handle\n" )); - return; - } -#endif - - cache = manager->caches[node->cache_index]; - -#ifdef FT_DEBUG_ERROR - if ( cache == NULL ) - { - FT_ERROR(( "FreeType.cache.node_destroy: invalid node handle\n" )); - return; - } -#endif - - clazz = cache->clazz; - - manager->cur_weight -= clazz->node_weight( node, cache ); - - /* remove node from mru list */ - ftc_node_mru_unlink( node, manager ); - - /* remove node from cache's hash table */ - ftc_node_hash_unlink( node, cache ); - - /* now finalize it */ - - if ( clazz->node_done ) - clazz->node_done( node, cache ); - - FREE( node ); - - /* check, just in case of general corruption :-) */ - if ( manager->num_nodes <= 0 ) - FT_ERROR(( "FTC_Manager_Compress: Invalid cache node count! = %d\n", - manager->num_nodes )); - } - - - FT_EXPORT_DEF( void ) + FT_EXPORT_DEF(void) FTC_Manager_Check( FTC_Manager manager ) { FTC_Node node, first; @@ -636,14 +590,23 @@ do { - FTC_Cache cache = manager->caches[node->cache_index]; - + FTC_FamilyEntry entry = manager->families.entries + node->fam_index; + FTC_Cache cache; - weight += cache->clazz->node_weight( node, cache ); - node = node->mru_next; + if ( (FT_UInt)node->fam_index >= manager->families.count || + entry->link != FTC_FAMILY_ENTRY_NONE ) + FT_ERROR(( "FTC_Manager_Compress: invalid node (family index = %ld\n", + node->fam_index )); + else + { + cache = entry->cache; + weight += cache->clazz->node_weight( node, cache ); + } + + node = node->mru_next; + } + while (node != first); - } while ( node != first ); - if ( weight != manager->cur_weight ) FT_ERROR(( "FTC_Manager_Compress: invalid weight %ld instead of %ld\n", @@ -654,22 +617,23 @@ if ( first ) { FT_UFast count = 0; - + node = first; do { count++; node = node->mru_next; + } + while (node != first); - } while ( node != first ); - if ( count != manager->num_nodes ) FT_ERROR(( "FTC_Manager_Compress: invalid cache node count %d instead of %d\n", manager->num_nodes, count )); } } +#endif /* FT_DEBUG_ERROR */ /* `Compress' the manager's data, i.e., get rid of old cache nodes */ @@ -689,7 +653,7 @@ first = manager->nodes_list; -#if 0 +#ifdef FT_DEBUG_ERROR FTC_Manager_Check( manager ); FT_ERROR(( "compressing, weight = %ld, max = %ld, nodes = %d\n", @@ -782,296 +746,20 @@ } - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** ABSTRACT CACHE CLASS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ -#define FTC_PRIMES_MIN 7 -#define FTC_PRIMES_MAX 13845163 - static const FT_UInt ftc_primes[] = + + + + FT_EXPORT_DEF(void) + FTC_Node_Unref( FTC_Node node, + FTC_Manager manager ) { - 7, - 11, - 19, - 37, - 73, - 109, - 163, - 251, - 367, - 557, - 823, - 1237, - 1861, - 2777, - 4177, - 6247, - 9371, - 14057, - 21089, - 31627, - 47431, - 71143, - 106721, - 160073, - 240101, - 360163, - 540217, - 810343, - 1215497, - 1823231, - 2734867, - 4102283, - 6153409, - 9230113, - 13845163, - }; - - - static FT_UFast - ftc_prime_closest( FT_UFast num ) - { - FT_UInt i; - - - for ( i = 0; i < sizeof ( ftc_primes ) / sizeof ( ftc_primes[0] ); i++ ) - if ( ftc_primes[i] > num ) - return ftc_primes[i]; - - return FTC_PRIMES_MAX; - } - - - FT_EXPORT_DEF( void ) - ftc_cache_resize( FTC_Cache cache ) - { - FT_UFast new_size; - - - new_size = ftc_prime_closest( cache->nodes ); - if ( new_size != cache->size ) + if ( node && (FT_UInt)node->fam_index < manager->families.count && + manager->families.entries[node->fam_index].cache ) { - FT_Memory memory = cache->memory; - FT_Error error; - FTC_Node* new_buckets ; - FT_ULong i; - - - if ( ALLOC_ARRAY( new_buckets, new_size, FTC_Node ) ) - return; - - for ( i = 0; i < cache->size; i++ ) - { - FTC_Node node, next, *pnode; - FT_UFast hash; - - - node = cache->buckets[i]; - while ( node ) - { - next = node->link; - hash = node->hash % new_size; - pnode = new_buckets + hash; - - node->link = pnode[0]; - pnode[0] = node; - - node = next; - } - } - - if ( cache->buckets ) - FREE( cache->buckets ); - - cache->buckets = new_buckets; - cache->size = new_size; - } - } - - - FT_EXPORT_DEF( FT_Error ) - ftc_cache_init( FTC_Cache cache ) - { - FT_Memory memory = cache->memory; - FT_Error error; - - - cache->nodes = 0; - cache->size = FTC_PRIMES_MIN; - - if ( ALLOC_ARRAY( cache->buckets, cache->size, FTC_Node ) ) - goto Exit; - - Exit: - return error; - } - - - FT_EXPORT_DEF( void ) - ftc_cache_done( FTC_Cache cache ) - { - if ( cache ) - { - FT_Memory memory = cache->memory; - FTC_Cache_Class clazz = cache->clazz; - FTC_Manager manager = cache->manager; - FT_UFast i; - - - for ( i = 0; i < cache->size; i++ ) - { - FTC_Node *pnode = cache->buckets + i, next, node = *pnode; - - while ( node ) - { - next = node->link; - node->link = NULL; - - /* remove node from mru list */ - ftc_node_mru_unlink( node, manager ); - - /* now finalize it */ - manager->cur_weight -= clazz->node_weight( node, cache ); - - if ( clazz->node_done ) - clazz->node_done( node, cache ); - - FREE( node ); - node = next; - } - cache->buckets[i] = NULL; - } - - FREE( cache->buckets ); - - cache->nodes = 0; - cache->size = 0; - } - } - - - /* Look up a node in "top" of its cache's hash table. */ - /* If not found, create a new node. */ - /* */ - FT_EXPORT_DEF( FT_Error ) - ftc_cache_lookup_node( FTC_Cache cache, - FT_UFast key_hash, - FT_Pointer key, - FTC_Node *anode ) - { - FT_Error error = 0; - FTC_Node result = NULL; - FTC_Node* bucket = cache->buckets + ( key_hash % cache->size ); - - - if ( *bucket ) - { - FTC_Node* pnode = bucket; - FTC_Node_CompareFunc compare = cache->clazz->node_compare; - - - for (;;) - { - FTC_Node node; - - - node = *pnode; - if ( node == NULL ) - break; - - if ( compare( node, key, cache ) ) - { - /* move to head of bucket list */ - if ( pnode != bucket ) - { - *pnode = node->link; - node->link = *bucket; - *bucket = node; - } - - /* move to head of MRU list */ - if ( node != cache->manager->nodes_list ) - ftc_node_mru_up( node, cache->manager ); - - result = node; - goto Exit; - } - - pnode = &(*pnode)->link; - } - } - - /* didn't find a node, create a new one */ - { - FTC_Cache_Class clazz = cache->clazz; - FTC_Manager manager = cache->manager; - FT_Memory memory = cache->memory; - FTC_Node node; - - - if ( ALLOC( node, clazz->node_size ) ) - goto Exit; - - /* node initializer must set 'hash' field */ - - node->cache_index = cache->cache_index; - node->ref_count = 0; - - error = clazz->node_init( node, key, cache ); - if ( error ) - { - FREE( node ); - goto Exit; - } - - ftc_node_hash_link( node, cache ); - ftc_node_mru_link( node, cache->manager ); - - cache->manager->cur_weight += clazz->node_weight( node, cache ); - - /* now try to compress the node pool when necessary */ - if ( manager->cur_weight >= manager->max_weight ) - { - node->ref_count++; - FTC_Manager_Compress( manager ); - node->ref_count--; - } - - /* try to resize the hash table when appropriate */ - if ( FTC_CACHE_RESIZE_TEST( cache ) ) - ftc_cache_resize( cache ); - - result = node; - } - - Exit: - *anode = result; - return error; - } - - - /* maybe the next two functions will disappear eventually */ - - FT_EXPORT_DEF( void ) - ftc_node_ref( FTC_Node node, - FTC_Cache cache ) - { - if ( node && cache && (FT_UInt)node->cache_index == cache->cache_index ) - node->ref_count++; - } - - - FT_EXPORT_DEF( void ) - ftc_node_unref( FTC_Node node, - FTC_Cache cache ) - { - if ( node && cache && (FT_UInt)node->cache_index == cache->cache_index ) node->ref_count--; + } } diff --git a/src/cache/ftcsbits.c b/src/cache/ftcsbits.c index 12548d129..e917e2d56 100644 --- a/src/cache/ftcsbits.c +++ b/src/cache/ftcsbits.c @@ -19,7 +19,7 @@ #include #include FT_CACHE_H #include FT_CACHE_SMALL_BITMAPS_H -#include FT_CACHE_INTERNAL_CHUNK_H +#include FT_CACHE_INTERNAL_GLYPH_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H #include FT_ERRORS_H @@ -32,29 +32,44 @@ #define FTC_SBIT_ITEMS_PER_NODE 16 - /* handle to sbit set */ - typedef struct FTC_SBitSetRec_* FTC_SBitSet; + typedef struct FTC_SBitNodeRec_* FTC_SBitNode; - /* sbit set structure */ - typedef struct FTC_SBitSetRec_ + typedef struct FTC_SBitNodeRec_ { - FTC_ChunkSetRec cset; - FTC_Image_Desc desc; + FTC_GlyphNodeRec gnode; + FTC_SBitRec sbits[ FTC_SBIT_ITEMS_PER_NODE ]; - } FTC_SBitSetRec; + } FTC_SBitNodeRec; +#define FTC_SBIT_NODE(x) ((FTC_SBitNode)(x)) -#define FTC_SBIT_SET( x ) ( (FTC_SBitSet)(x) ) -#define FTC_SBIT_SET_MEMORY( x ) FTC_CHUNK_SET_MEMORY( &(x)->cset ) typedef struct FTC_SBitQueryRec_ { - FTC_ChunkQueryRec chunk; - FTC_Image_Desc desc; + FTC_GlyphQueryRec gquery; + FTC_ImageDesc desc; } FTC_SBitQueryRec, *FTC_SBitQuery; +#define FTC_SBIT_QUERY(x) ((FTC_SBitQuery)(x)) + + + + typedef struct FTC_SBitFamilyRec_* FTC_SBitFamily; + + /* sbit family structure */ + typedef struct FTC_SBitFamilyRec_ + { + FTC_GlyphFamilyRec gfam; + FTC_ImageDesc desc; + + } FTC_SBitFamilyRec; + +#define FTC_SBIT_FAMILY( x ) ( (FTC_SBitFamily)(x) ) +#define FTC_SBIT_FAMILY_MEMORY( x ) FTC_GLYPH_FAMILY_MEMORY( &(x)->cset ) + + /*************************************************************************/ /*************************************************************************/ @@ -65,31 +80,10 @@ /*************************************************************************/ - FT_CALLBACK_DEF( void ) - ftc_sbit_node_done( FTC_ChunkNode cnode ) - { - FTC_ChunkSet cset = cnode->cset; - FT_Memory memory = cset->ccache->cache.memory; - FT_UInt count = cnode->item_count; - FTC_SBit sbit = (FTC_SBit) cnode->items; - - - if ( sbit ) - { - for ( ; count > 0; sbit++, count-- ) - FREE( sbit->buffer ); - - FREE( cnode->items ); - } - - ftc_chunk_node_done( cnode ); - } - - static FT_Error - ftc_sbit_set_bitmap( FTC_SBit sbit, - FT_Bitmap* bitmap, - FT_Memory memory ) + ftc_sbit_copy_bitmap( FTC_SBit sbit, + FT_Bitmap* bitmap, + FT_Memory memory ) { FT_Error error; FT_Int pitch = bitmap->pitch; @@ -108,49 +102,69 @@ } + + FT_CALLBACK_DEF( void ) + ftc_sbit_node_done( FTC_SBitNode snode, + FTC_Cache cache ) + { + FTC_SBit sbit = snode->sbits; + FT_UInt count = FTC_GLYPH_NODE(snode)->item_count; + FT_Memory memory = cache->memory; + + + for ( ; count > 0; sbit++, count-- ) + FREE( sbit->buffer ); + + ftc_glyph_node_done( FTC_GLYPH_NODE(snode), cache ); + } + + static FT_Error - ftc_sbit_node_load( FTC_ChunkNode cnode, - FT_UInt gindex, - FT_ULong *asize ) + ftc_sbit_node_load( FTC_SBitNode snode, + FTC_Manager manager, + FT_UInt gindex, + FT_ULong *asize ) { FT_Error error; - FTC_ChunkSet cset = cnode->cset; - FTC_SBitSet sbitset = FTC_SBIT_SET(cset); - FT_Memory memory = FTC_SBIT_SET_MEMORY(sbitset); + FTC_GlyphNode gnode = FTC_GLYPH_NODE(snode); + FTC_GlyphFamily gfam; + FTC_SBitFamily sfam; + FT_Memory memory; FT_Face face; FT_Size size; - FTC_SBit sbit; - - if ( gindex < (FT_UInt)cnode->item_start || - gindex >= (FT_UInt)cnode->item_start + cnode->item_count ) + if ( gindex < (FT_UInt)gnode->item_start || + gindex >= (FT_UInt)gnode->item_start + gnode->item_count ) { FT_ERROR(( "FreeType.cache.sbit_load: invalid glyph index" )); return FTC_Err_Invalid_Argument; } - sbit = (FTC_SBit)cnode->items + ( gindex - cnode->item_start ); + gfam = FTC_GLYPH_FAMILY( manager->families.entries[ gnode->node.fam_index ].family ); + sfam = FTC_SBIT_FAMILY(gfam); + memory = manager->library->memory; - error = FTC_Manager_Lookup_Size( cset->ccache->cache.manager, - &sbitset->desc.font, + sbit = snode->sbits + (gindex - gnode->item_start); + + error = FTC_Manager_Lookup_Size( manager, &sfam->desc.font, &face, &size ); if ( !error ) { FT_UInt load_flags = FT_LOAD_DEFAULT; - FT_UInt image_type = sbitset->desc.image_type; + FT_UInt type = sfam->desc.type; /* determine load flags, depending on the font description's */ /* image type */ - if ( FTC_IMAGE_FORMAT( image_type ) == ftc_image_format_bitmap ) + if ( FTC_IMAGE_FORMAT( type ) == ftc_image_format_bitmap ) { - if ( image_type & ftc_image_flag_monochrome ) + if ( type & ftc_image_flag_monochrome ) load_flags |= FT_LOAD_MONOCHROME; /* disable embedded bitmaps loading if necessary */ - if ( image_type & ftc_image_flag_no_sbits ) + if ( type & ftc_image_flag_no_sbits ) load_flags |= FT_LOAD_NO_BITMAP; } else @@ -165,10 +179,10 @@ /* always render glyphs to bitmaps */ load_flags |= FT_LOAD_RENDER; - if ( image_type & ftc_image_flag_unhinted ) + if ( type & ftc_image_flag_unhinted ) load_flags |= FT_LOAD_NO_HINTING; - if ( image_type & ftc_image_flag_autohinted ) + if ( type & ftc_image_flag_autohinted ) load_flags |= FT_LOAD_FORCE_AUTOHINT; /* by default, indicates a `missing' glyph */ @@ -222,13 +236,13 @@ else { /* copy the bitmap into a new buffer -- ignore error */ - error = ftc_sbit_set_bitmap( sbit, bitmap, memory ); + error = ftc_sbit_copy_bitmap( sbit, bitmap, memory ); } /* now, compute size */ if ( asize ) - *asize = ABS( sbit->pitch ) * sbit->height; - + *asize = ABS(sbit->pitch) * sbit->height; + } /* glyph dimensions ok */ } /* glyph loading successful */ @@ -251,45 +265,39 @@ FT_CALLBACK_DEF( FT_Error ) - ftc_sbit_node_init( FTC_ChunkNode cnode, - FTC_ChunkQuery query ) + ftc_sbit_node_init( FTC_SBitNode snode, + FTC_GlyphQuery gquery, + FTC_Cache cache ) { FT_Error error; + ftc_glyph_node_init( FTC_GLYPH_NODE(snode), + gquery->gindex, + FTC_GLYPH_FAMILY(gquery->query.family) ); - error = ftc_chunk_node_init( cnode, - query->cset, - query->gindex, - TRUE ); - if ( !error ) - { - error = ftc_sbit_node_load( cnode, query->gindex, NULL ); - - if ( error ) - ftc_chunk_node_done( cnode ); - } + error = ftc_sbit_node_load( snode, cache->manager, gquery->gindex, NULL ); + if ( error ) + ftc_glyph_node_done( FTC_GLYPH_NODE(snode), cache ); return error; } - /* this function is important because it is both part of */ - /* an FTC_ChunkSet_Class and an FTC_CacheNode_Class */ - /* */ FT_CALLBACK_DEF( FT_ULong ) - ftc_sbit_node_weight( FTC_ChunkNode cnode ) + ftc_sbit_node_weight( FTC_SBitNode snode ) { - FT_ULong size; - FT_UInt count = cnode->item_count; - FT_Int pitch; - FTC_SBit sbit = (FTC_SBit) cnode->items; + FTC_GlyphNode gnode = FTC_GLYPH_NODE(snode); + FT_UInt count = gnode->item_count; + FTC_SBit sbit = snode->sbits; + FT_Int pitch; + FT_ULong size; /* the node itself */ - size = sizeof ( *cnode ); + size = sizeof ( *snode ); /* the sbit records */ - size += cnode->item_count * sizeof ( FTC_SBitRec ); + size += FTC_GLYPH_NODE(snode)->item_count * sizeof ( FTC_SBitRec ); for ( ; count > 0; count--, sbit++ ) { @@ -309,30 +317,26 @@ FT_CALLBACK_DEF( FT_Bool ) - ftc_sbit_node_compare( FTC_ChunkNode cnode, - FTC_SBitQuery query, + ftc_sbit_node_compare( FTC_SBitNode snode, + FTC_SBitQuery squery, FTC_Cache cache ) { - FTC_ChunkQuery creq = &query->chunk; - FT_UInt gindex = query->chunk.gindex; - FT_UInt offset = (FT_UInt)(gindex - cnode->item_start); + FTC_GlyphQuery gquery = FTC_GLYPH_QUERY(squery); + FTC_GlyphNode gnode = FTC_GLYPH_NODE(snode); FT_Bool result; - - result = FT_BOOL( offset < (FT_UInt)cnode->item_count && - creq->cset == cnode->cset ); + result = ftc_glyph_node_compare( gnode, gquery ); if ( result ) { /* check if we need to load the glyph bitmap now */ - FTC_SBit sbit = (FTC_SBit)cnode->items + offset; - + FT_UInt gindex = gquery->gindex; + FTC_SBit sbit = snode->sbits + (gindex - gnode->item_start); if ( sbit->buffer == NULL && sbit->width != 255 ) { FT_ULong size; - - ftc_sbit_node_load( cnode, gindex, &size ); + ftc_sbit_node_load( snode, cache->manager, gindex, &size ); cache->manager->cur_weight += size; } } @@ -344,41 +348,35 @@ /*************************************************************************/ /*************************************************************************/ /***** *****/ - /***** SBIT CHUNK SETS *****/ + /***** SBITS FAMILIES *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_CALLBACK_DEF( FT_Error ) - ftc_sbit_set_init( FTC_SBitSet sset, - FTC_SBitQuery query, - FT_LruList lru ) + ftc_sbit_family_init( FTC_SBitFamily sfam, + FTC_SBitQuery squery, + FTC_Cache cache ) { - FTC_ChunkCache ccache = lru->user_data; - FTC_Manager manager = ccache->cache.manager; - FT_Error error; - FT_Face face; + FTC_Manager manager = cache->manager; + FT_Error error; + FT_Face face; - - sset->desc = query->desc; + sfam->desc = squery->desc; /* we need to compute "cquery.item_total" now */ error = FTC_Manager_Lookup_Face( manager, - query->desc.font.face_id, + squery->desc.font.face_id, &face ); if ( !error ) { - ftc_chunk_set_init( FTC_CHUNK_SET( sset ), - sizeof ( FTC_SBitRec ), - FTC_SBIT_ITEMS_PER_NODE, - face->num_glyphs, - FTC_CHUNK_CACHE( lru->user_data ) ); - - /* now compute hash from description -- this is _very_ important */ - /* for good performance */ - sset->cset.hash = FTC_IMAGE_DESC_HASH( &sset->desc ); - query->chunk.cset = &sset->cset; + error = ftc_glyph_family_init( FTC_GLYPH_FAMILY(sfam), + FTC_IMAGE_DESC_HASH( &sfam->desc ), + FTC_SBIT_ITEMS_PER_NODE, + face->num_glyphs, + FTC_GLYPH_QUERY(squery), + cache ); } return error; @@ -386,37 +384,23 @@ FT_CALLBACK_DEF( FT_Bool ) - ftc_sbit_set_compare( FTC_SBitSet sset, - FTC_SBitQuery query ) + ftc_sbit_family_compare( FTC_SBitFamily sfam, + FTC_SBitQuery squery ) { FT_Bool result; /* we need to set the "cquery.cset" field or our query for */ - /* faster glyph comparisons in ftc_sbit_node_compare() */ - /* */ - result = FT_BOOL( FTC_IMAGE_DESC_COMPARE( &sset->desc, &query->desc ) ); + /* faster glyph comparisons in ftc_sbit_node_compare.. */ + /* */ + result = FT_BOOL( FTC_IMAGE_DESC_COMPARE( &sfam->desc, &squery->desc ) ); if ( result ) - query->chunk.cset = &sset->cset; + FTC_GLYPH_FAMILY_FOUND(sfam,squery); return result; } - FT_CALLBACK_TABLE_DEF - const FT_LruList_ClassRec ftc_sbit_set_class = - { - sizeof ( FT_LruListRec ), - (FT_LruList_InitFunc) NULL, - (FT_LruList_DoneFunc) NULL, - - sizeof ( FTC_SBitSetRec ), - (FT_LruNode_InitFunc) ftc_sbit_set_init, - (FT_LruNode_DoneFunc) ftc_chunk_set_done, - (FT_LruNode_FlushFunc) NULL, - (FT_LruNode_CompareFunc)ftc_sbit_set_compare, - }; - /*************************************************************************/ /*************************************************************************/ @@ -427,34 +411,33 @@ /*************************************************************************/ - FT_CALLBACK_DEF( FT_Error ) - ftc_sbit_cache_init( FTC_SBit_Cache scache ) - { - return ftc_chunk_cache_init( FTC_CHUNK_CACHE( scache ), - &ftc_sbit_set_class ); - } - FT_CALLBACK_TABLE_DEF const FTC_Cache_ClassRec ftc_sbit_cache_class = { - sizeof ( FTC_ChunkCacheRec ), - (FTC_Cache_InitFunc) ftc_sbit_cache_init, - (FTC_Cache_DoneFunc) ftc_chunk_cache_done, + sizeof( FTC_CacheRec ), + (FTC_Cache_InitFunc) ftc_cache_init, + (FTC_Cache_ClearFunc) ftc_cache_clear, + (FTC_Cache_DoneFunc) ftc_cache_done, - sizeof ( FTC_ChunkNodeRec ), - (FTC_Node_InitFunc) ftc_sbit_node_init, - (FTC_Node_WeightFunc) ftc_sbit_node_weight, - (FTC_Node_CompareFunc)ftc_sbit_node_compare, - (FTC_Node_DoneFunc) ftc_sbit_node_done + sizeof( FTC_SBitFamilyRec ), + (FTC_Family_InitFunc) ftc_sbit_family_init, + (FTC_Family_CompareFunc) ftc_sbit_family_compare, + (FTC_Family_DoneFunc) ftc_glyph_family_done, + + sizeof( FTC_SBitNodeRec ), + (FTC_Node_InitFunc) ftc_sbit_node_init, + (FTC_Node_WeightFunc) ftc_sbit_node_weight, + (FTC_Node_CompareFunc) ftc_sbit_node_compare, + (FTC_Node_DoneFunc) ftc_sbit_node_done }; /* documentation is in ftcsbits.h */ FT_EXPORT_DEF( FT_Error ) - FTC_SBit_Cache_New( FTC_Manager manager, - FTC_SBit_Cache *acache ) + FTC_SBitCache_New( FTC_Manager manager, + FTC_SBitCache *acache ) { return FTC_Manager_Register_Cache( manager, &ftc_sbit_cache_class, @@ -465,34 +448,77 @@ /* documentation is in ftcsbits.h */ FT_EXPORT_DEF( FT_Error ) - FTC_SBit_Cache_Lookup( FTC_SBit_Cache cache, - FTC_Image_Desc* desc, - FT_UInt gindex, - FTC_SBit *ansbit ) + FTC_SBitCache_Lookup( FTC_SBitCache cache, + FTC_ImageDesc* desc, + FT_UInt gindex, + FTC_SBit *ansbit, + FTC_Node *anode ) { FT_Error error; - FTC_ChunkCache ccache = (FTC_ChunkCache) cache; - FTC_ChunkNode node; - FTC_SBitQueryRec query; + FTC_SBitQueryRec squery; + FTC_SBitNode node; - - /* argument checks delayed to FTC_Chunk_Cache_Lookup */ + /* argument checks delayed to ftc_cache_lookup */ if ( !ansbit ) return FTC_Err_Invalid_Argument; *ansbit = NULL; - query.chunk.gindex = gindex; - query.chunk.cset = NULL; - query.desc = *desc; - - error = ftc_chunk_cache_lookup( ccache, &query.chunk, &node ); + if ( anode ) + *anode = NULL; + + squery.gquery.gindex = gindex; + squery.desc = *desc; + + error = ftc_cache_lookup( FTC_CACHE(cache), + FTC_QUERY(&squery), + (FTC_Node*) &node ); if ( !error ) { - *ansbit = (FTC_SBit)node->items + ( gindex - node->item_start ); + *ansbit = node->sbits + (gindex - FTC_GLYPH_NODE(node)->item_start); + + if ( anode ) + { + *anode = FTC_NODE(node); + FTC_NODE(node)->ref_count ++; + } } return error; } + + /* backwards-compatibility functions */ + + FT_EXPORT_DEF( FT_Error ) + FTC_SBit_Cache_New( FTC_Manager manager, + FTC_SBit_Cache *acache ) + { + return FTC_SBitCache_New( manager, (FTC_SBitCache*)acache ); + } + + + FT_EXPORT_DEF( FT_Error ) + FTC_SBit_Cache_Lookup( FTC_SBit_Cache cache, + FTC_Image_Desc* desc, + FT_UInt gindex, + FTC_SBit *ansbit ) + { + FTC_ImageDesc desc0; + + if ( !desc ) + return FT_Err_Invalid_Argument; + + desc0.font = desc->font; + desc0.type = (FT_UInt32) desc->image_type; + + return FTC_SBitCache_Lookup( (FTC_SBitCache)cache, + &desc0, + gindex, + ansbit, + NULL ); + } + + + /* END */ diff --git a/src/cache/ftlru.c b/src/cache/ftlru.c index 5c4183b7c..6d2c897c6 100644 --- a/src/cache/ftlru.c +++ b/src/cache/ftlru.c @@ -46,7 +46,7 @@ list->clazz = clazz; list->memory = memory; list->max_nodes = max_nodes; - list->user_data = user_data; + list->data = user_data; if ( clazz->list_init ) { @@ -110,7 +110,7 @@ if ( clazz->node_done ) - clazz->node_done( node, list ); + clazz->node_done( node, list->data ); FREE( node ); node = next; @@ -151,7 +151,7 @@ if ( node == NULL ) break; - if ( clazz->node_compare( node, key, list ) ) + if ( clazz->node_compare( node, key, list->data ) ) break; plast = pnode; @@ -203,15 +203,15 @@ { if ( clazz->node_flush ) { - error = clazz->node_flush( last, key, list ); + error = clazz->node_flush( last, key, list->data ); } else { if ( clazz->node_done ) - clazz->node_done( last, list ); + clazz->node_done( last, list->data ); last->key = key; - error = clazz->node_init( last, key, list ); + error = clazz->node_init( last, key, list->data ); } if ( !error ) @@ -228,7 +228,7 @@ /* in case of error during the flush or done/init cycle, */ /* we need to discard the node */ if ( clazz->node_done ) - clazz->node_done( last, list ); + clazz->node_done( last, list->data ); *plast = NULL; list->num_nodes--; @@ -243,7 +243,7 @@ goto Exit; node->key = key; - error = clazz->node_init( node, key, list ); + error = clazz->node_init( node, key, list->data ); if ( error ) { FREE( node ); @@ -284,7 +284,7 @@ node->next = NULL; if ( clazz->node_done ) - clazz->node_done( node, list ); + clazz->node_done( node, list->data ); FREE( node ); list->num_nodes--; @@ -319,7 +319,7 @@ if ( node == NULL ) break; - if ( select_func( node, select_data, list ) ) + if ( select_func( node, select_data, list->data ) ) { *pnode = node->next; node->next = NULL; diff --git a/src/cache/rules.mk b/src/cache/rules.mk index 1e84af2f1..0620cddf6 100644 --- a/src/cache/rules.mk +++ b/src/cache/rules.mk @@ -30,8 +30,8 @@ Cache_COMPILE := $(FT_COMPILE) $I$(CACHE_DIR) # Cache_DRV_SRC := $(CACHE_DIR_)ftlru.c \ $(CACHE_DIR_)ftcmanag.c \ + $(CACHE_DIR_)ftccache.c \ $(CACHE_DIR_)ftcglyph.c \ - $(CACHE_DIR_)ftcchunk.c \ $(CACHE_DIR_)ftcsbits.c \ $(CACHE_DIR_)ftcimage.c diff --git a/src/pshinter/pshalgo1.c b/src/pshinter/pshalgo1.c index d8b3022a8..010ac5781 100644 --- a/src/pshinter/pshalgo1.c +++ b/src/pshinter/pshalgo1.c @@ -220,7 +220,7 @@ FT_ERROR(( "%s.init: missing/incorrect hint masks!\n" )); - count = table->max_hints; + Count = table->max_hints; for ( Index = 0; Index < Count; Index++ ) psh1_hint_table_record( table, Index ); } diff --git a/src/pshinter/pshalgo2.c b/src/pshinter/pshalgo2.c index 4bfd3553c..6b27ec69c 100644 --- a/src/pshinter/pshalgo2.c +++ b/src/pshinter/pshalgo2.c @@ -217,7 +217,7 @@ FT_ERROR(( "%s.init: missing/incorrect hint masks!\n" )); - count = table->max_hints; + Count = table->max_hints; for ( Index = 0; Index < Count; Index++ ) psh2_hint_table_record( table, Index ); } @@ -1495,15 +1495,12 @@ FT_Outline* outline, PSH_Globals globals ) { - PSH2_Glyph glyph; PSH2_GlyphRec glyphrec; + PSH2_Glyph glyph = &glyphrec; FT_Error error; FT_Memory memory; FT_Int dimension; - FT_UNUSED(glyphrec); - - memory = globals->memory; #ifdef DEBUG_HINTER @@ -1517,8 +1514,6 @@ return error; ps2_debug_glyph = glyph; -#else - glyph = &glyphrec; #endif error = psh2_glyph_init( glyph, outline, ps_hints, globals );