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..
This commit is contained in:
David Turner 2001-12-05 15:59:33 +00:00
parent c3b2160869
commit 14183ea0f8
22 changed files with 1340 additions and 1417 deletions

View File

@ -1,3 +1,20 @@
2001-12-05 David Turner <david@freetype.org>
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 <freetype@davidkrause.com>
* docs/license.txt: s/X Windows/X Window System/.

251
include/freetype/cache/ftccache.h vendored Normal file
View File

@ -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__ */

View File

@ -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 <ft2build.h>
#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 */

View File

@ -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__ */

View File

@ -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
/*************************************************************************/
/* */
/* <Struct> */
/* FTC_ImageDesc */
/* */
/* <Description> */
/* A simple structure used to describe a given glyph image category. */
/* note that this is different from @FTC_Image_Desc */
/* */
/* <Fields> */
/* 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 */
/* */
/* <Note> */
/* 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) )
/*************************************************************************/
/* */
/* <Type> */
/* FTC_ImageCache */
/* */
/* <Description> */
/* 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;
/*************************************************************************/
/* */
/* <Function> */
/* FTC_ImageCache_New */
/* */
/* <Description> */
/* Creates a new glyph image cache. */
/* */
/* <Input> */
/* manager :: The parent manager for the image cache. */
/* */
/* <Output> */
/* acache :: A handle to the new glyph image cache object. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
FT_EXPORT( FT_Error )
FTC_ImageCache_New( FTC_Manager manager,
FTC_ImageCache *acache );
/*************************************************************************/
/* */
/* <Function> */
/* FTC_ImageCache_Lookup */
/* */
/* <Description> */
/* 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 */
/* */
/* <Input> */
/* cache :: A handle to the source glyph image cache. */
/* */
/* desc :: A pointer to a glyph image descriptor. */
/* */
/* gindex :: The glyph index to retrieve. */
/* */
/* <Output> */
/* 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 */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* 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 );
/* */
/*************************************************************************/
/* */
/* <Struct> */
/* FTC_Image_Desc */
/* */
/* <Description> */
/* THIS TYPE IS DEPRECATED. USE @FTC_ImageDesc instead.. */
/* A simple structure used to describe a given glyph image category. */
/* */
/* <Fields> */
@ -88,6 +210,9 @@ FT_BEGIN_HEADER
/* */
/* image_type :: The glyph image's type. */
/* */
/* <Note> */
/* */
/* */
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) )
/*************************************************************************/
/* */
/* <Type> */
/* FTC_Image_Cache */
/* */
/* <Description> */
/* 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 */
/* */
/* <Description> */
/* THIS FUNCTION IS DEPRECATED, USE @FTC_ImageCache_New instead */
/* Creates a new glyph image cache. */
/* */
/* <Input> */
@ -147,7 +262,7 @@ FT_BEGIN_HEADER
/* FTC_Image_Cache_Lookup */
/* */
/* <Description> */
/* Retrieves a given glyph image from a glyph image cache. */
/* THIS FUNCTION IS DEPRECATED. USE @FTC_ImageCache_Lookup instead */
/* */
/* <Input> */
/* 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

View File

@ -66,7 +66,7 @@
#include <ft2build.h>
#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 );
/* */

View File

@ -48,20 +48,6 @@ FT_BEGIN_HEADER
typedef struct FTC_SBitRec_* FTC_SBit;
/*************************************************************************/
/* */
/* <Type> */
/* FTC_SBit_Cache */
/* */
/* <Description> */
/* 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;
/*************************************************************************/
/* */
/* <Struct> */
@ -112,6 +98,100 @@ FT_BEGIN_HEADER
} FTC_SBitRec;
/*************************************************************************/
/* */
/* <Type> */
/* FTC_SBit_Cache */
/* */
/* <Description> */
/* 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;
/*************************************************************************/
/* */
/* <Type> */
/* FTC_SBit_Cache */
/* */
/* <Description> */
/* deprecated. please use @FTC_SBitCache instead */
/* */
typedef FTC_SBitCache FTC_SBit_Cache;
/*************************************************************************/
/* */
/* <Function> */
/* FTC_SBitCache_New */
/* */
/* <Description> */
/* Creates a new cache to store small glyph bitmaps. */
/* */
/* <Input> */
/* manager :: A handle to the source cache manager. */
/* */
/* <Output> */
/* acache :: A handle to the new sbit cache. NULL in case of error. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
FT_EXPORT( FT_Error )
FTC_SBitCache_New( FTC_Manager manager,
FTC_SBitCache *acache );
/*************************************************************************/
/* */
/* <Function> */
/* FTC_SBitCache_Lookup */
/* */
/* <Description> */
/* Looks up a given small glyph bitmap in a given sbit cache and */
/* "lock" it to prevent its flushing from the cache until needed */
/* */
/* <Input> */
/* cache :: A handle to the source sbit cache. */
/* desc :: A pointer to the glyph image descriptor. */
/* gindex :: The glyph index. */
/* */
/* <Output> */
/* 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 */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* 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 );
/* */
/*************************************************************************/
/* */
/* <Function> */
@ -169,9 +249,6 @@ FT_BEGIN_HEADER
FTC_SBit *sbit );
/* */
FT_END_HEADER
#endif /* __FTCSBITS_H__ */

View File

@ -58,14 +58,11 @@
#ifndef __FTLRU_H__
#define __FTLRU_H__
#include <ft2build.h>
#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__ */

View File

@ -467,7 +467,7 @@
#define FT_CACHE_INTERNAL_LRU_H <freetype/cache/ftlru.h>
#define FT_CACHE_INTERNAL_GLYPH_H <freetype/cache/ftcglyph.h>
#define FT_CACHE_INTERNAL_CHUNK_H <freetype/cache/ftcchunk.h>
#define FT_CACHE_INTERNAL_CACHE_H <freetype/cache/ftccache.h>
/* now include internal headers definitions from <freetype/internal/...> */

View File

@ -57,6 +57,37 @@ FT_BEGIN_HEADER
/* This section describes the FreeType 2 cache sub-system which is */
/* stile in beta. */
/* */
/* <Order> */
/* 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) )
/*************************************************************************/
/* */
/* <Type> */
@ -192,6 +222,26 @@ FT_BEGIN_HEADER
typedef struct FTC_ManagerRec_* FTC_Manager;
/*************************************************************************/
/* */
/* <Type> */
/* FTC_Node */
/* */
/* <Description> */
/* 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;
/*************************************************************************/
/* */
/* <Function> */
@ -349,6 +399,24 @@ FT_BEGIN_HEADER
FT_Face *aface,
FT_Size *asize );
/*************************************************************************/
/* */
/* <Function> */
/* FTC_Node_Unref */
/* */
/* <Description> */
/* decrement a cache node's internal reference count. when the count */
/* reaches 0, it is not destroyed but becomes eligible for subsequent */
/* cache flushes.. */
/* */
/* <Input> */
/* node :: cache node handle */
/* manager :: cache manager handle */
/* */
FT_EXPORT( void )
FTC_Node_Unref( FTC_Node node,
FTC_Manager manager );
/* */

View File

@ -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... */

View File

@ -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 */

2
src/cache/Jamfile vendored
View File

@ -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
{

2
src/cache/ftcache.c vendored
View File

@ -21,8 +21,8 @@
#include <ft2build.h>
#include "ftlru.c"
#include "ftcmanag.c"
#include "ftccache.c"
#include "ftcglyph.c"
#include "ftcchunk.c"
#include "ftcimage.c"
#include "ftcsbits.c"

167
src/cache/ftcglyph.c vendored
View File

@ -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 */

238
src/cache/ftcimage.c vendored
View File

@ -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 );
}

782
src/cache/ftcmanag.c vendored
View File

@ -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--;
}
}

358
src/cache/ftcsbits.c vendored
View File

@ -19,7 +19,7 @@
#include <ft2build.h>
#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 */

20
src/cache/ftlru.c vendored
View File

@ -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;

2
src/cache/rules.mk vendored
View File

@ -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

View File

@ -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 );
}

View File

@ -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 );