parent
eae8ba6ed2
commit
80182bc177
18 changed files with 3419 additions and 3433 deletions
@ -1,251 +1,251 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ftccache.h */ |
||||
/* */ |
||||
/* FreeType internal cache interface (specification). */ |
||||
/* */ |
||||
/* Copyright 2000-2001, 2002 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used, */ |
||||
/* modified, and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#ifndef __FTCCACHE_H__ |
||||
#define __FTCCACHE_H__ |
||||
|
||||
|
||||
#include FT_CACHE_INTERNAL_MRU_H |
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
/* handle to cache object */ |
||||
typedef struct FTC_CacheRec_* FTC_Cache; |
||||
|
||||
/* handle to cache class */ |
||||
typedef const struct FTC_CacheClassRec_* FTC_CacheClass; |
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/***** *****/ |
||||
/***** 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_MruNodeRec mru; /* 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) ) |
||||
|
||||
#define FTC_NODE__NEXT(x) FTC_NODE( (x)->mru.next ) |
||||
#define FTC_NODE__PREV(x) FTC_NODE( (x)->mru.prev ) |
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* 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. */ |
||||
/* */ |
||||
|
||||
/* reserved for manager's use */ |
||||
FT_EXPORT( void ) |
||||
ftc_node_destroy( FTC_Node node, |
||||
FTC_Manager manager ); |
||||
|
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/***** *****/ |
||||
/***** CACHE DEFINITIONS *****/ |
||||
/***** *****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
/* initialize a new cache node */ |
||||
typedef FT_Error (*FTC_Node_NewFunc)( FTC_Node *pnode, |
||||
FT_Pointer query, |
||||
FTC_Cache cache ); |
||||
|
||||
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 ); |
||||
|
||||
|
||||
typedef void (*FTC_Node_FreeFunc)( FTC_Node node, |
||||
FTC_Cache cache ); |
||||
|
||||
typedef FT_Error (*FTC_Cache_InitFunc)( FTC_Cache cache ); |
||||
|
||||
typedef void (*FTC_Cache_DoneFunc)( FTC_Cache cache ); |
||||
|
||||
|
||||
typedef struct FTC_CacheClassRec_ |
||||
{ |
||||
FTC_Node_NewFunc node_new; |
||||
FTC_Node_WeightFunc node_weight; |
||||
FTC_Node_CompareFunc node_compare; |
||||
FTC_Node_CompareFunc node_remove_faceid; |
||||
FTC_Node_FreeFunc node_free; |
||||
|
||||
FT_UInt cache_size; |
||||
FTC_Cache_InitFunc cache_init; |
||||
FTC_Cache_DoneFunc cache_done; |
||||
|
||||
} FTC_CacheClassRec; |
||||
|
||||
/* each cache really implements a dynamic hash table to manage its nodes */ |
||||
typedef struct FTC_CacheRec_ |
||||
{ |
||||
FT_UFast p; |
||||
FT_UFast mask; |
||||
FT_Long slack; |
||||
FTC_Node* buckets; |
||||
|
||||
FTC_CacheClassRec clazz; /* local copy, for speed */ |
||||
|
||||
FTC_Manager manager; |
||||
FT_Memory memory; |
||||
FT_UInt index; /* in manager's table */ |
||||
|
||||
FTC_CacheClass org_class; /* original class pointer */ |
||||
|
||||
} FTC_CacheRec; |
||||
|
||||
|
||||
#define FTC_CACHE( x ) ( (FTC_Cache)(x) ) |
||||
#define FTC_CACHE_P( x ) ( (FTC_Cache*)(x) ) |
||||
|
||||
|
||||
/* default cache initialize */ |
||||
FT_EXPORT( FT_Error ) |
||||
FTC_Cache_Init( FTC_Cache cache ); |
||||
|
||||
/* default cache finalizer */ |
||||
FT_EXPORT( void ) |
||||
FTC_Cache_Done( FTC_Cache cache ); |
||||
|
||||
/* call this function to lookup the cache. if no corresponding
|
||||
* node is found, a new one is automatically created. This function |
||||
* is capable of flushing the cache adequately to make room for the |
||||
* new cache object. |
||||
*/ |
||||
FT_EXPORT( FT_Error ) |
||||
FTC_Cache_Lookup( FTC_Cache cache, |
||||
FT_UInt32 hash, |
||||
FT_Pointer query, |
||||
FTC_Node *anode ); |
||||
|
||||
FT_EXPORT( FT_Error ) |
||||
FTC_Cache_NewNode( FTC_Cache cache, |
||||
FT_UInt32 hash, |
||||
FT_Pointer query, |
||||
FTC_Node *anode ); |
||||
|
||||
/* remove all nodes that relate to a given face_id. This is useful
|
||||
* when un-installing fonts. Note that if a cache node relates to |
||||
* the face_id, but is locked (i.e. has 'ref_count > 0'), the node |
||||
* will _not_ be destroyed, but its internal face_id reference will |
||||
* be modified. |
||||
* |
||||
* the end result will be that the node will never come back |
||||
* in further lookup requests, and will be flushed on demand from |
||||
* the cache normally when its reference count reaches 0 |
||||
*/ |
||||
FT_EXPORT( void ) |
||||
FTC_Cache_RemoveFaceID( FTC_Cache cache, |
||||
FTC_FaceID face_id ); |
||||
|
||||
|
||||
|
||||
#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \ |
||||
FT_BEGIN_STMNT \
|
||||
FTC_Node *_bucket, *_pnode, _node; \
|
||||
FTC_Cache _cache = FTC_CACHE(cache); \
|
||||
FT_UInt32 _hash = (FT_UInt32)(hash); \
|
||||
FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \
|
||||
FT_UInt _idx; \
|
||||
\
|
||||
error = 0; \
|
||||
_idx = _hash & _cache->mask; \
|
||||
if ( _idx < _cache->p ) \
|
||||
_idx = _hash & (_cache->mask*2 + 1); \
|
||||
\
|
||||
_bucket = _pnode = _cache->buckets + _idx; \
|
||||
for (;;) \
|
||||
{ \
|
||||
_node = *_pnode; \
|
||||
if ( _node == NULL ) \
|
||||
goto _NewNode; \
|
||||
\
|
||||
if ( _node->hash == _hash && _nodcomp( _node, query, _cache ) ) \
|
||||
break; \
|
||||
\
|
||||
_pnode = &_node->link; \
|
||||
} \
|
||||
\
|
||||
if ( _node != *_bucket ) \
|
||||
{ \
|
||||
*_pnode = _node->link; \
|
||||
_node->link = *_bucket; \
|
||||
*_bucket = _node; \
|
||||
} \
|
||||
\
|
||||
{ \
|
||||
FTC_Manager _manager = _cache->manager; \
|
||||
\
|
||||
if ( _node != _manager->nodes_list ) \
|
||||
FTC_MruNode_Up( (FTC_MruNode*)&_manager->nodes_list, \
|
||||
(FTC_MruNode)_node ); \
|
||||
} \
|
||||
goto _Ok; \
|
||||
\
|
||||
_NewNode: \
|
||||
error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \
|
||||
\
|
||||
_Ok: \
|
||||
*(FTC_Node*)&(node) = _node; \
|
||||
FT_END_STMNT |
||||
|
||||
|
||||
/* */ |
||||
|
||||
FT_END_HEADER |
||||
|
||||
|
||||
#endif /* __FTCCACHE_H__ */ |
||||
|
||||
|
||||
/* END */ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ftccache.h */ |
||||
/* */ |
||||
/* FreeType internal cache interface (specification). */ |
||||
/* */ |
||||
/* Copyright 2000-2001, 2002 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used, */ |
||||
/* modified, and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#ifndef __FTCCACHE_H__ |
||||
#define __FTCCACHE_H__ |
||||
|
||||
|
||||
#include FT_CACHE_INTERNAL_MRU_H |
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
/* handle to cache object */ |
||||
typedef struct FTC_CacheRec_* FTC_Cache; |
||||
|
||||
/* handle to cache class */ |
||||
typedef const struct FTC_CacheClassRec_* FTC_CacheClass; |
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/***** *****/ |
||||
/***** 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_MruNodeRec mru; /* 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) ) |
||||
|
||||
#define FTC_NODE__NEXT(x) FTC_NODE( (x)->mru.next ) |
||||
#define FTC_NODE__PREV(x) FTC_NODE( (x)->mru.prev ) |
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* 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. */ |
||||
/* */ |
||||
|
||||
/* reserved for manager's use */ |
||||
FT_EXPORT( void ) |
||||
ftc_node_destroy( FTC_Node node, |
||||
FTC_Manager manager ); |
||||
|
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/***** *****/ |
||||
/***** CACHE DEFINITIONS *****/ |
||||
/***** *****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
/* initialize a new cache node */ |
||||
typedef FT_Error (*FTC_Node_NewFunc)( FTC_Node *pnode, |
||||
FT_Pointer query, |
||||
FTC_Cache cache ); |
||||
|
||||
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 ); |
||||
|
||||
|
||||
typedef void (*FTC_Node_FreeFunc)( FTC_Node node, |
||||
FTC_Cache cache ); |
||||
|
||||
typedef FT_Error (*FTC_Cache_InitFunc)( FTC_Cache cache ); |
||||
|
||||
typedef void (*FTC_Cache_DoneFunc)( FTC_Cache cache ); |
||||
|
||||
|
||||
typedef struct FTC_CacheClassRec_ |
||||
{ |
||||
FTC_Node_NewFunc node_new; |
||||
FTC_Node_WeightFunc node_weight; |
||||
FTC_Node_CompareFunc node_compare; |
||||
FTC_Node_CompareFunc node_remove_faceid; |
||||
FTC_Node_FreeFunc node_free; |
||||
|
||||
FT_UInt cache_size; |
||||
FTC_Cache_InitFunc cache_init; |
||||
FTC_Cache_DoneFunc cache_done; |
||||
|
||||
} FTC_CacheClassRec; |
||||
|
||||
/* each cache really implements a dynamic hash table to manage its nodes */ |
||||
typedef struct FTC_CacheRec_ |
||||
{ |
||||
FT_UFast p; |
||||
FT_UFast mask; |
||||
FT_Long slack; |
||||
FTC_Node* buckets; |
||||
|
||||
FTC_CacheClassRec clazz; /* local copy, for speed */ |
||||
|
||||
FTC_Manager manager; |
||||
FT_Memory memory; |
||||
FT_UInt index; /* in manager's table */ |
||||
|
||||
FTC_CacheClass org_class; /* original class pointer */ |
||||
|
||||
} FTC_CacheRec; |
||||
|
||||
|
||||
#define FTC_CACHE( x ) ( (FTC_Cache)(x) ) |
||||
#define FTC_CACHE_P( x ) ( (FTC_Cache*)(x) ) |
||||
|
||||
|
||||
/* default cache initialize */ |
||||
FT_EXPORT( FT_Error ) |
||||
FTC_Cache_Init( FTC_Cache cache ); |
||||
|
||||
/* default cache finalizer */ |
||||
FT_EXPORT( void ) |
||||
FTC_Cache_Done( FTC_Cache cache ); |
||||
|
||||
/* call this function to lookup the cache. if no corresponding
|
||||
* node is found, a new one is automatically created. This function |
||||
* is capable of flushing the cache adequately to make room for the |
||||
* new cache object. |
||||
*/ |
||||
FT_EXPORT( FT_Error ) |
||||
FTC_Cache_Lookup( FTC_Cache cache, |
||||
FT_UInt32 hash, |
||||
FT_Pointer query, |
||||
FTC_Node *anode ); |
||||
|
||||
FT_EXPORT( FT_Error ) |
||||
FTC_Cache_NewNode( FTC_Cache cache, |
||||
FT_UInt32 hash, |
||||
FT_Pointer query, |
||||
FTC_Node *anode ); |
||||
|
||||
/* remove all nodes that relate to a given face_id. This is useful
|
||||
* when un-installing fonts. Note that if a cache node relates to |
||||
* the face_id, but is locked (i.e. has 'ref_count > 0'), the node |
||||
* will _not_ be destroyed, but its internal face_id reference will |
||||
* be modified. |
||||
* |
||||
* the end result will be that the node will never come back |
||||
* in further lookup requests, and will be flushed on demand from |
||||
* the cache normally when its reference count reaches 0 |
||||
*/ |
||||
FT_EXPORT( void ) |
||||
FTC_Cache_RemoveFaceID( FTC_Cache cache, |
||||
FTC_FaceID face_id ); |
||||
|
||||
|
||||
|
||||
#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \ |
||||
FT_BEGIN_STMNT \
|
||||
FTC_Node *_bucket, *_pnode, _node; \
|
||||
FTC_Cache _cache = FTC_CACHE(cache); \
|
||||
FT_UInt32 _hash = (FT_UInt32)(hash); \
|
||||
FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \
|
||||
FT_UInt _idx; \
|
||||
\
|
||||
error = 0; \
|
||||
_idx = _hash & _cache->mask; \
|
||||
if ( _idx < _cache->p ) \
|
||||
_idx = _hash & (_cache->mask*2 + 1); \
|
||||
\
|
||||
_bucket = _pnode = _cache->buckets + _idx; \
|
||||
for (;;) \
|
||||
{ \
|
||||
_node = *_pnode; \
|
||||
if ( _node == NULL ) \
|
||||
goto _NewNode; \
|
||||
\
|
||||
if ( _node->hash == _hash && _nodcomp( _node, query, _cache ) ) \
|
||||
break; \
|
||||
\
|
||||
_pnode = &_node->link; \
|
||||
} \
|
||||
\
|
||||
if ( _node != *_bucket ) \
|
||||
{ \
|
||||
*_pnode = _node->link; \
|
||||
_node->link = *_bucket; \
|
||||
*_bucket = _node; \
|
||||
} \
|
||||
\
|
||||
{ \
|
||||
FTC_Manager _manager = _cache->manager; \
|
||||
\
|
||||
if ( _node != _manager->nodes_list ) \
|
||||
FTC_MruNode_Up( (FTC_MruNode*)&_manager->nodes_list, \
|
||||
(FTC_MruNode)_node ); \
|
||||
} \
|
||||
goto _Ok; \
|
||||
\
|
||||
_NewNode: \
|
||||
error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \
|
||||
\
|
||||
_Ok: \
|
||||
*(FTC_Node*)&(node) = _node; \
|
||||
FT_END_STMNT |
||||
|
||||
|
||||
/* */ |
||||
|
||||
FT_END_HEADER |
||||
|
||||
|
||||
#endif /* __FTCCACHE_H__ */ |
||||
|
||||
|
||||
/* END */ |
||||
|
@ -1,295 +1,295 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ftcglyph.h */ |
||||
/* */ |
||||
/* FreeType abstract glyph cache (specification). */ |
||||
/* */ |
||||
/* Copyright 2000-2001, 2003 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. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
/*
|
||||
* |
||||
* FTC_GCache is an _abstract_ cache object optimized to store glyph |
||||
* data. It works as follows: |
||||
* |
||||
* - it manages FTC_GNode objects. Each one of them can hold one or more |
||||
* glyph "items". Item types are not specified in the FTC_GCache but in |
||||
* classes that extend it |
||||
* |
||||
* - glyph attributes, like face_id, character size, render mode, etc.. |
||||
* can be grouped in abstract "glyph families". This avoids storing |
||||
* the attributes within the FTC_GCache, since it is likely that many |
||||
* FTC_GNodes will belong to the same family in typical uses |
||||
* |
||||
* - each FTC_GNode is thus a FTC_Node with two additionnal fields: |
||||
* |
||||
* * gindex :: a glyph index, or the first index in a glyph range |
||||
* * family :: a pointer to a glyph "family" |
||||
* |
||||
* - Family types are not fully specific in the FTC_Family type, but |
||||
* by classes that extend it. |
||||
* |
||||
* Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache. They |
||||
* share an FTC_Family sub-class called FTC_BasicFamily which is used to |
||||
* store the following data: face_id, pixel/point sizes, load flags. |
||||
* for more details, see the file "src/cache/ftcbasic.c" |
||||
* |
||||
* Client applications can extend FTC_GNode with their own FTC_GNode |
||||
* and FTC_Family sub-classes to implement more complex caches (e.g. |
||||
* handling automatic synthetis, like obliquing & emboldening, colored |
||||
* glyphs, etc...) |
||||
* |
||||
* See also the FTC_ICache & FTC_SCache classes in "ftcimage.h" and |
||||
* "ftcsbits.h", which both extend FTC_GCache with additionnal |
||||
* optimizations. |
||||
* |
||||
* |
||||
* a typical FTC_GCache implementation must provide at least the following: |
||||
* |
||||
* - FTC_GNode sub-class, e.g. MyNode, with relevant methods, i.e: |
||||
* my_node_new ( must call FTC_GNode_Init ) |
||||
* my_node_free ( must call FTC_GNode_Done ) |
||||
* my_node_compare ( must call FTC_GNode_Compare ) |
||||
* my_node_remove_faceid ( must call ftc_gnode_unselect in case |
||||
* of match ) |
||||
* |
||||
* |
||||
* - FTC_Family sub-class, e.g. MyFamily, with relevant methods, e.g.: |
||||
* my_family_compare |
||||
* my_family_init |
||||
* my_family_reset (optional) |
||||
* my_family_done |
||||
* |
||||
* - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query |
||||
* data. |
||||
* |
||||
* - provide constant structures for a FTC_GNodeClass |
||||
* |
||||
* - MyCacheNew() can be implemented easily as a call to the convenience |
||||
* function FTC_GCache_New |
||||
* |
||||
* - implement MyCacheLookup with a call to FTC_GCache_Lookup. This |
||||
* function will automatically: |
||||
* |
||||
* - search for the corresponding family in the cache, or create |
||||
* a new one if necessary. put it in FTC_GQUERY(myquery).family |
||||
* |
||||
* - call FTC_Cache_Lookup |
||||
* |
||||
* if it returns NULL, you should create a new node, then call |
||||
* ftc_cache_add as usual. |
||||
*/ |
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* Important: The functions defined in this file are only used to */ |
||||
/* implement an abstract glyph cache class. You need to */ |
||||
/* provide additional logic to implement a complete cache. */ |
||||
/* */ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/********* *********/ |
||||
/********* WARNING, THIS IS BETA CODE. *********/ |
||||
/********* *********/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
#ifndef __FTCGLYPH_H__ |
||||
#define __FTCGLYPH_H__ |
||||
|
||||
|
||||
#include <ft2build.h> |
||||
#include FT_CACHE_INTERNAL_MANAGER_H |
||||
|
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
|
||||
/*
|
||||
* we can group glyph in "families". Each family correspond to a |
||||
* given face id, character size, transform, etc... |
||||
* |
||||
* families are implemented as MRU list nodes. They are reference-counted |
||||
*/ |
||||
|
||||
typedef struct FTC_FamilyRec_ |
||||
{ |
||||
FTC_MruNodeRec mrunode; |
||||
FT_UInt num_nodes; /* current number of nodes in this family */ |
||||
FTC_Cache cache; |
||||
FTC_MruListClass clazz; |
||||
|
||||
} FTC_FamilyRec, *FTC_Family; |
||||
|
||||
#define FTC_FAMILY(x) ( (FTC_Family)(x) ) |
||||
#define FTC_FAMILY_P(x) ( (FTC_Family*)(x) ) |
||||
|
||||
|
||||
typedef struct FTC_GNodeRec_ |
||||
{ |
||||
FTC_NodeRec node; |
||||
FTC_Family family; |
||||
FT_UInt gindex; |
||||
|
||||
} FTC_GNodeRec, *FTC_GNode; |
||||
|
||||
#define FTC_GNODE( x ) ( (FTC_GNode)(x) ) |
||||
#define FTC_GNODE_P( x ) ( (FTC_GNode*)(x) ) |
||||
|
||||
|
||||
typedef struct FTC_GQueryRec_ |
||||
{ |
||||
FT_UInt gindex; |
||||
FTC_Family family; |
||||
|
||||
} FTC_GQueryRec, *FTC_GQuery; |
||||
|
||||
#define FTC_GQUERY( x ) ( (FTC_GQuery)(x) ) |
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* 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. */ |
||||
/* */ |
||||
|
||||
/* must be called by derived FTC_Node_InitFunc routines */ |
||||
FT_EXPORT( void ) |
||||
FTC_GNode_Init( FTC_GNode node, |
||||
FT_UInt gindex, /* glyph index for node */ |
||||
FTC_Family family ); |
||||
|
||||
/* returns TRUE iff the query's glyph index correspond to the node; */ |
||||
/* this assumes that the "family" and "hash" fields of the query are */ |
||||
/* already correctly set */ |
||||
FT_EXPORT( FT_Bool ) |
||||
FTC_GNode_Compare( FTC_GNode gnode, |
||||
FTC_GQuery gquery ); |
||||
|
||||
/* call this function to clear a node's family. this is necessary
|
||||
* to implement the "node_remove_faceid" cache method correctly |
||||
*/ |
||||
FT_EXPORT( void ) |
||||
FTC_GNode_UnselectFamily( FTC_GNode gnode, |
||||
FTC_Cache cache ); |
||||
|
||||
/* must be called by derived FTC_Node_DoneFunc routines */ |
||||
FT_EXPORT( void ) |
||||
FTC_GNode_Done( FTC_GNode node, |
||||
FTC_Cache cache ); |
||||
|
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_Family_Init( FTC_Family family, |
||||
FTC_Cache cache ); |
||||
|
||||
typedef struct FTC_GCacheRec_ |
||||
{ |
||||
FTC_CacheRec cache; |
||||
FTC_MruListRec families; |
||||
|
||||
} FTC_GCacheRec, *FTC_GCache; |
||||
|
||||
|
||||
#define FTC_GCACHE(x) ((FTC_GCache)(x)) |
||||
|
||||
|
||||
/* can be used as @FTC_Cache_InitFunc */ |
||||
FT_EXPORT( FT_Error ) |
||||
FTC_GCache_Init( FTC_GCache cache ); |
||||
|
||||
|
||||
/* can be used as @FTC_Cache_DoneFunc */ |
||||
FT_EXPORT( void ) |
||||
FTC_GCache_Done( FTC_GCache cache ); |
||||
|
||||
|
||||
/* the glyph cache class adds fields for the family implementation */ |
||||
typedef struct FTC_GCacheClassRec_ |
||||
{ |
||||
FTC_CacheClassRec clazz; |
||||
FTC_MruListClass family_class; |
||||
|
||||
} FTC_GCacheClassRec; |
||||
|
||||
typedef const FTC_GCacheClassRec* FTC_GCacheClass; |
||||
|
||||
#define FTC_GCACHE_CLASS(x) ((FTC_GCacheClass)(x)) |
||||
|
||||
#define FTC_CACHE__GCACHE_CLASS(x) FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class ) |
||||
#define FTC_CACHE__FAMILY_CLASS(x) ((FTC_MruListClass) FTC_CACHE__GCACHE_CLASS(x)->family_class) |
||||
|
||||
|
||||
/* convenience function. use instead of FTC_Manager_Register_Cache */ |
||||
FT_EXPORT( FT_Error ) |
||||
FTC_GCache_New( FTC_Manager manager, |
||||
FTC_GCacheClass clazz, |
||||
FTC_GCache *acache ); |
||||
|
||||
FT_EXPORT( FT_Error ) |
||||
FTC_GCache_Lookup( FTC_GCache cache, |
||||
FT_UInt32 hash, |
||||
FT_UInt gindex, |
||||
FTC_GQuery query, |
||||
FTC_Node *anode ); |
||||
|
||||
|
||||
#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, gindex, query, node, error ) \ |
||||
FT_BEGIN_STMNT \
|
||||
FTC_GCache _gcache = FTC_GCACHE( cache ); \
|
||||
FTC_Family _family; \
|
||||
FTC_GQuery _gquery = (FTC_GQuery)( query ); \
|
||||
FTC_MruNode_CompareFunc _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \
|
||||
\
|
||||
_gquery->gindex = (gindex); \
|
||||
\
|
||||
FTC_MRULIST_LOOP( &_gcache->families, _family ) \
|
||||
{ \
|
||||
if ( _fcompare( (FTC_MruNode)_family, _gquery ) ) \
|
||||
{ \
|
||||
_gquery->family = _family; \
|
||||
goto _FamilyFound; \
|
||||
} \
|
||||
} \
|
||||
FTC_MRULIST_LOOP_END(); \
|
||||
\
|
||||
error = FTC_MruList_New( &_gcache->families, \
|
||||
_gquery, \
|
||||
(FTC_MruNode*)&_gquery->family ); \
|
||||
if ( !error ) \
|
||||
{ \
|
||||
_FamilyFound: \
|
||||
FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ); \
|
||||
} \
|
||||
FT_END_STMNT |
||||
/* */ |
||||
|
||||
FT_END_HEADER |
||||
|
||||
|
||||
#endif /* __FTCGLYPH_H__ */ |
||||
|
||||
|
||||
/* END */ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ftcglyph.h */ |
||||
/* */ |
||||
/* FreeType abstract glyph cache (specification). */ |
||||
/* */ |
||||
/* Copyright 2000-2001, 2003 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. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
/*
|
||||
* |
||||
* FTC_GCache is an _abstract_ cache object optimized to store glyph |
||||
* data. It works as follows: |
||||
* |
||||
* - it manages FTC_GNode objects. Each one of them can hold one or more |
||||
* glyph "items". Item types are not specified in the FTC_GCache but in |
||||
* classes that extend it |
||||
* |
||||
* - glyph attributes, like face_id, character size, render mode, etc.. |
||||
* can be grouped in abstract "glyph families". This avoids storing |
||||
* the attributes within the FTC_GCache, since it is likely that many |
||||
* FTC_GNodes will belong to the same family in typical uses |
||||
* |
||||
* - each FTC_GNode is thus a FTC_Node with two additionnal fields: |
||||
* |
||||
* * gindex :: a glyph index, or the first index in a glyph range |
||||
* * family :: a pointer to a glyph "family" |
||||
* |
||||
* - Family types are not fully specific in the FTC_Family type, but |
||||
* by classes that extend it. |
||||
* |
||||
* Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache. They |
||||
* share an FTC_Family sub-class called FTC_BasicFamily which is used to |
||||
* store the following data: face_id, pixel/point sizes, load flags. |
||||
* for more details, see the file "src/cache/ftcbasic.c" |
||||
* |
||||
* Client applications can extend FTC_GNode with their own FTC_GNode |
||||
* and FTC_Family sub-classes to implement more complex caches (e.g. |
||||
* handling automatic synthetis, like obliquing & emboldening, colored |
||||
* glyphs, etc...) |
||||
* |
||||
* See also the FTC_ICache & FTC_SCache classes in "ftcimage.h" and |
||||
* "ftcsbits.h", which both extend FTC_GCache with additionnal |
||||
* optimizations. |
||||
* |
||||
* |
||||
* a typical FTC_GCache implementation must provide at least the following: |
||||
* |
||||
* - FTC_GNode sub-class, e.g. MyNode, with relevant methods, i.e: |
||||
* my_node_new ( must call FTC_GNode_Init ) |
||||
* my_node_free ( must call FTC_GNode_Done ) |
||||
* my_node_compare ( must call FTC_GNode_Compare ) |
||||
* my_node_remove_faceid ( must call ftc_gnode_unselect in case |
||||
* of match ) |
||||
* |
||||
* |
||||
* - FTC_Family sub-class, e.g. MyFamily, with relevant methods, e.g.: |
||||
* my_family_compare |
||||
* my_family_init |
||||
* my_family_reset (optional) |
||||
* my_family_done |
||||
* |
||||
* - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query |
||||
* data. |
||||
* |
||||
* - provide constant structures for a FTC_GNodeClass |
||||
* |
||||
* - MyCacheNew() can be implemented easily as a call to the convenience |
||||
* function FTC_GCache_New |
||||
* |
||||
* - implement MyCacheLookup with a call to FTC_GCache_Lookup. This |
||||
* function will automatically: |
||||
* |
||||
* - search for the corresponding family in the cache, or create |
||||
* a new one if necessary. put it in FTC_GQUERY(myquery).family |
||||
* |
||||
* - call FTC_Cache_Lookup |
||||
* |
||||
* if it returns NULL, you should create a new node, then call |
||||
* ftc_cache_add as usual. |
||||
*/ |
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* Important: The functions defined in this file are only used to */ |
||||
/* implement an abstract glyph cache class. You need to */ |
||||
/* provide additional logic to implement a complete cache. */ |
||||
/* */ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/********* *********/ |
||||
/********* WARNING, THIS IS BETA CODE. *********/ |
||||
/********* *********/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
#ifndef __FTCGLYPH_H__ |
||||
#define __FTCGLYPH_H__ |
||||
|
||||
|
||||
#include <ft2build.h> |
||||
#include FT_CACHE_INTERNAL_MANAGER_H |
||||
|
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
|
||||
/*
|
||||
* we can group glyph in "families". Each family correspond to a |
||||
* given face id, character size, transform, etc... |
||||
* |
||||
* families are implemented as MRU list nodes. They are reference-counted |
||||
*/ |
||||
|
||||
typedef struct FTC_FamilyRec_ |
||||
{ |
||||
FTC_MruNodeRec mrunode; |
||||
FT_UInt num_nodes; /* current number of nodes in this family */ |
||||
FTC_Cache cache; |
||||
FTC_MruListClass clazz; |
||||
|
||||
} FTC_FamilyRec, *FTC_Family; |
||||
|
||||
#define FTC_FAMILY(x) ( (FTC_Family)(x) ) |
||||
#define FTC_FAMILY_P(x) ( (FTC_Family*)(x) ) |
||||
|
||||
|
||||
typedef struct FTC_GNodeRec_ |
||||
{ |
||||
FTC_NodeRec node; |
||||
FTC_Family family; |
||||
FT_UInt gindex; |
||||
|
||||
} FTC_GNodeRec, *FTC_GNode; |
||||
|
||||
#define FTC_GNODE( x ) ( (FTC_GNode)(x) ) |
||||
#define FTC_GNODE_P( x ) ( (FTC_GNode*)(x) ) |
||||
|
||||
|
||||
typedef struct FTC_GQueryRec_ |
||||
{ |
||||
FT_UInt gindex; |
||||
FTC_Family family; |
||||
|
||||
} FTC_GQueryRec, *FTC_GQuery; |
||||
|
||||
#define FTC_GQUERY( x ) ( (FTC_GQuery)(x) ) |
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* 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. */ |
||||
/* */ |
||||
|
||||
/* must be called by derived FTC_Node_InitFunc routines */ |
||||
FT_EXPORT( void ) |
||||
FTC_GNode_Init( FTC_GNode node, |
||||
FT_UInt gindex, /* glyph index for node */ |
||||
FTC_Family family ); |
||||
|
||||
/* returns TRUE iff the query's glyph index correspond to the node; */ |
||||
/* this assumes that the "family" and "hash" fields of the query are */ |
||||
/* already correctly set */ |
||||
FT_EXPORT( FT_Bool ) |
||||
FTC_GNode_Compare( FTC_GNode gnode, |
||||
FTC_GQuery gquery ); |
||||
|
||||
/* call this function to clear a node's family. this is necessary
|
||||
* to implement the "node_remove_faceid" cache method correctly |
||||
*/ |
||||
FT_EXPORT( void ) |
||||
FTC_GNode_UnselectFamily( FTC_GNode gnode, |
||||
FTC_Cache cache ); |
||||
|
||||
/* must be called by derived FTC_Node_DoneFunc routines */ |
||||
FT_EXPORT( void ) |
||||
FTC_GNode_Done( FTC_GNode node, |
||||
FTC_Cache cache ); |
||||
|
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_Family_Init( FTC_Family family, |
||||
FTC_Cache cache ); |
||||
|
||||
typedef struct FTC_GCacheRec_ |
||||
{ |
||||
FTC_CacheRec cache; |
||||
FTC_MruListRec families; |
||||
|
||||
} FTC_GCacheRec, *FTC_GCache; |
||||
|
||||
|
||||
#define FTC_GCACHE(x) ((FTC_GCache)(x)) |
||||
|
||||
|
||||
/* can be used as @FTC_Cache_InitFunc */ |
||||
FT_EXPORT( FT_Error ) |
||||
FTC_GCache_Init( FTC_GCache cache ); |
||||
|
||||
|
||||
/* can be used as @FTC_Cache_DoneFunc */ |
||||
FT_EXPORT( void ) |
||||
FTC_GCache_Done( FTC_GCache cache ); |
||||
|
||||
|
||||
/* the glyph cache class adds fields for the family implementation */ |
||||
typedef struct FTC_GCacheClassRec_ |
||||
{ |
||||
FTC_CacheClassRec clazz; |
||||
FTC_MruListClass family_class; |
||||
|
||||
} FTC_GCacheClassRec; |
||||
|
||||
typedef const FTC_GCacheClassRec* FTC_GCacheClass; |
||||
|
||||
#define FTC_GCACHE_CLASS(x) ((FTC_GCacheClass)(x)) |
||||
|
||||
#define FTC_CACHE__GCACHE_CLASS(x) FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class ) |
||||
#define FTC_CACHE__FAMILY_CLASS(x) ((FTC_MruListClass) FTC_CACHE__GCACHE_CLASS(x)->family_class) |
||||
|
||||
|
||||
/* convenience function. use instead of FTC_Manager_Register_Cache */ |
||||
FT_EXPORT( FT_Error ) |
||||
FTC_GCache_New( FTC_Manager manager, |
||||
FTC_GCacheClass clazz, |
||||
FTC_GCache *acache ); |
||||
|
||||
FT_EXPORT( FT_Error ) |
||||
FTC_GCache_Lookup( FTC_GCache cache, |
||||
FT_UInt32 hash, |
||||
FT_UInt gindex, |
||||
FTC_GQuery query, |
||||
FTC_Node *anode ); |
||||
|
||||
|
||||
#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, gindex, query, node, error ) \ |
||||
FT_BEGIN_STMNT \
|
||||
FTC_GCache _gcache = FTC_GCACHE( cache ); \
|
||||
FTC_Family _family; \
|
||||
FTC_GQuery _gquery = (FTC_GQuery)( query ); \
|
||||
FTC_MruNode_CompareFunc _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \
|
||||
\
|
||||
_gquery->gindex = (gindex); \
|
||||
\
|
||||
FTC_MRULIST_LOOP( &_gcache->families, _family ) \
|
||||
{ \
|
||||
if ( _fcompare( (FTC_MruNode)_family, _gquery ) ) \
|
||||
{ \
|
||||
_gquery->family = _family; \
|
||||
goto _FamilyFound; \
|
||||
} \
|
||||
} \
|
||||
FTC_MRULIST_LOOP_END(); \
|
||||
\
|
||||
error = FTC_MruList_New( &_gcache->families, \
|
||||
_gquery, \
|
||||
(FTC_MruNode*)&_gquery->family ); \
|
||||
if ( !error ) \
|
||||
{ \
|
||||
_FamilyFound: \
|
||||
FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ); \
|
||||
} \
|
||||
FT_END_STMNT |
||||
/* */ |
||||
|
||||
FT_END_HEADER |
||||
|
||||
|
||||
#endif /* __FTCGLYPH_H__ */ |
||||
|
||||
|
||||
/* END */ |
||||
|
@ -1,227 +1,227 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ftcmru.h */ |
||||
/* */ |
||||
/* Simple MRU list-cache (specification). */ |
||||
/* */ |
||||
/* Copyright 2000-2001, 2003 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. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* An MRU is a list that cannot hold more than a certain number of */ |
||||
/* elements (`max_elements'). All elements in the list are sorted in */ |
||||
/* least-recently-used order, i.e., the `oldest' element is at the tail */ |
||||
/* of the list. */ |
||||
/* */ |
||||
/* When doing a lookup (either through `Lookup()' or `Lookup_Node()'), */ |
||||
/* the list is searched for an element with the corresponding key. If */ |
||||
/* it is found, the element is moved to the head of the list and is */ |
||||
/* returned. */ |
||||
/* */ |
||||
/* If no corresponding element is found, the lookup routine will try to */ |
||||
/* obtain a new element with the relevant key. If the list is already */ |
||||
/* full, the oldest element from the list is discarded and replaced by a */ |
||||
/* new one; a new element is added to the list otherwise. */ |
||||
/* */ |
||||
/* Note that it is possible to pre-allocate the element list nodes. */ |
||||
/* This is handy if `max_elements' is sufficiently small, as it saves */ |
||||
/* allocations/releases during the lookup process. */ |
||||
/* */ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
#ifndef __FTCMRU_H__ |
||||
#define __FTCMRU_H__ |
||||
|
||||
|
||||
#include <ft2build.h> |
||||
#include FT_FREETYPE_H |
||||
|
||||
#ifdef FREETYPE_H |
||||
#error "freetype.h of FreeType 1 has been loaded!" |
||||
#error "Please fix the directory search order for header files" |
||||
#error "so that freetype.h of FreeType 2 is found first." |
||||
#endif |
||||
|
||||
#define xxFT_DEBUG_ERROR |
||||
#define FTC_INLINE |
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
typedef struct FTC_MruNodeRec_* FTC_MruNode; |
||||
|
||||
typedef struct FTC_MruNodeRec_ |
||||
{ |
||||
FTC_MruNode next; |
||||
FTC_MruNode prev; |
||||
|
||||
} FTC_MruNodeRec; |
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruNode_Prepend( FTC_MruNode *plist, |
||||
FTC_MruNode node ); |
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruNode_Up( FTC_MruNode *plist, |
||||
FTC_MruNode node ); |
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruNode_Remove( FTC_MruNode *plist, |
||||
FTC_MruNode node ); |
||||
|
||||
typedef struct FTC_MruListRec_* FTC_MruList; |
||||
|
||||
typedef struct FTC_MruListClassRec_ const * FTC_MruListClass; |
||||
|
||||
typedef FT_Int (*FTC_MruNode_CompareFunc)( FTC_MruNode node, |
||||
FT_Pointer key ); |
||||
|
||||
typedef FT_Error (*FTC_MruNode_InitFunc)( FTC_MruNode node, |
||||
FT_Pointer key, |
||||
FT_Pointer data ); |
||||
|
||||
typedef FT_Error (*FTC_MruNode_ResetFunc)( FTC_MruNode node, |
||||
FT_Pointer key, |
||||
FT_Pointer data ); |
||||
|
||||
typedef void (*FTC_MruNode_DoneFunc)( FTC_MruNode node, |
||||
FT_Pointer data ); |
||||
|
||||
typedef struct FTC_MruListClassRec_ |
||||
{ |
||||
FT_UInt node_size; |
||||
FTC_MruNode_CompareFunc node_compare; |
||||
FTC_MruNode_InitFunc node_init; |
||||
FTC_MruNode_ResetFunc node_reset; |
||||
FTC_MruNode_DoneFunc node_done; |
||||
|
||||
} FTC_MruListClassRec; |
||||
|
||||
typedef struct FTC_MruListRec_ |
||||
{ |
||||
FT_UInt num_nodes; |
||||
FT_UInt max_nodes; |
||||
FTC_MruNode nodes; |
||||
FT_Pointer data; |
||||
FTC_MruListClassRec clazz; |
||||
FT_Memory memory; |
||||
|
||||
} FTC_MruListRec; |
||||
|
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruList_Init( FTC_MruList list, |
||||
FTC_MruListClass clazz, |
||||
FT_UInt max_nodes, |
||||
FT_Pointer data, |
||||
FT_Memory memory ); |
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruList_Reset( FTC_MruList list ); |
||||
|
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruList_Done( FTC_MruList list ); |
||||
|
||||
FT_EXPORT( FTC_MruNode ) |
||||
FTC_MruList_Find( FTC_MruList list, |
||||
FT_Pointer key ); |
||||
|
||||
FT_EXPORT( FT_Error ) |
||||
FTC_MruList_New( FTC_MruList list, |
||||
FT_Pointer key, |
||||
FTC_MruNode *anode ); |
||||
|
||||
FT_EXPORT( FT_Error ) |
||||
FTC_MruList_Lookup( FTC_MruList list, |
||||
FT_Pointer key, |
||||
FTC_MruNode *pnode ); |
||||
|
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruList_Remove( FTC_MruList list, |
||||
FTC_MruNode node ); |
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruList_RemoveSelection( FTC_MruList list, |
||||
FTC_MruNode_CompareFunc select, |
||||
FT_Pointer key ); |
||||
|
||||
|
||||
#ifdef FTC_INLINE |
||||
|
||||
#define FTC_MRULIST_LOOKUP( list, key, node, error ) \ |
||||
FT_BEGIN_STMNT \
|
||||
FTC_MruNode_CompareFunc _compare = (list)->clazz.node_compare; \
|
||||
FTC_MruNode _first, _node; \
|
||||
\
|
||||
error = 0; \
|
||||
_first = (list)->nodes; \
|
||||
_node = NULL; \
|
||||
\
|
||||
if ( _first ) \
|
||||
{ \
|
||||
_node = _first; \
|
||||
do \
|
||||
{ \
|
||||
if ( _compare( _node, (key) ) ) \
|
||||
{ \
|
||||
*(FTC_MruNode*)&(node) = _node; \
|
||||
goto _Ok; \
|
||||
} \
|
||||
_node = _node->next; \
|
||||
} \
|
||||
while ( _node != _first) ; \
|
||||
} \
|
||||
\
|
||||
error = FTC_MruList_New( (list), (key), (FTC_MruNode*)&(node) ); \
|
||||
_Ok: \
|
||||
; \
|
||||
FT_END_STMNT |
||||
|
||||
#else /* !FTC_INLINE */ |
||||
|
||||
#define FTC_MRULIST_LOOKUP_CMP( list, key, node, error ) \ |
||||
error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) )
|
||||
|
||||
#endif /* !FTC_INLINE */ |
||||
|
||||
|
||||
#define FTC_MRULIST_LOOP( list, node ) \ |
||||
FT_BEGIN_STMNT \
|
||||
FTC_MruNode _first = (list)->nodes; \
|
||||
\
|
||||
if ( _first ) \
|
||||
{ \
|
||||
FTC_MruNode _node = _first; \
|
||||
do \
|
||||
{ \
|
||||
*(FTC_MruNode*)&(node) = _node; |
||||
|
||||
|
||||
#define FTC_MRULIST_LOOP_END() \ |
||||
_node = _node->next; \
|
||||
} \
|
||||
while ( _node != _first ); \
|
||||
} \
|
||||
FT_END_STMNT |
||||
|
||||
/* */ |
||||
|
||||
FT_END_HEADER |
||||
|
||||
|
||||
#endif /* __FTCMRU_H__ */ |
||||
|
||||
|
||||
/* END */ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ftcmru.h */ |
||||
/* */ |
||||
/* Simple MRU list-cache (specification). */ |
||||
/* */ |
||||
/* Copyright 2000-2001, 2003 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. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* An MRU is a list that cannot hold more than a certain number of */ |
||||
/* elements (`max_elements'). All elements in the list are sorted in */ |
||||
/* least-recently-used order, i.e., the `oldest' element is at the tail */ |
||||
/* of the list. */ |
||||
/* */ |
||||
/* When doing a lookup (either through `Lookup()' or `Lookup_Node()'), */ |
||||
/* the list is searched for an element with the corresponding key. If */ |
||||
/* it is found, the element is moved to the head of the list and is */ |
||||
/* returned. */ |
||||
/* */ |
||||
/* If no corresponding element is found, the lookup routine will try to */ |
||||
/* obtain a new element with the relevant key. If the list is already */ |
||||
/* full, the oldest element from the list is discarded and replaced by a */ |
||||
/* new one; a new element is added to the list otherwise. */ |
||||
/* */ |
||||
/* Note that it is possible to pre-allocate the element list nodes. */ |
||||
/* This is handy if `max_elements' is sufficiently small, as it saves */ |
||||
/* allocations/releases during the lookup process. */ |
||||
/* */ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
#ifndef __FTCMRU_H__ |
||||
#define __FTCMRU_H__ |
||||
|
||||
|
||||
#include <ft2build.h> |
||||
#include FT_FREETYPE_H |
||||
|
||||
#ifdef FREETYPE_H |
||||
#error "freetype.h of FreeType 1 has been loaded!" |
||||
#error "Please fix the directory search order for header files" |
||||
#error "so that freetype.h of FreeType 2 is found first." |
||||
#endif |
||||
|
||||
#define xxFT_DEBUG_ERROR |
||||
#define FTC_INLINE |
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
typedef struct FTC_MruNodeRec_* FTC_MruNode; |
||||
|
||||
typedef struct FTC_MruNodeRec_ |
||||
{ |
||||
FTC_MruNode next; |
||||
FTC_MruNode prev; |
||||
|
||||
} FTC_MruNodeRec; |
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruNode_Prepend( FTC_MruNode *plist, |
||||
FTC_MruNode node ); |
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruNode_Up( FTC_MruNode *plist, |
||||
FTC_MruNode node ); |
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruNode_Remove( FTC_MruNode *plist, |
||||
FTC_MruNode node ); |
||||
|
||||
typedef struct FTC_MruListRec_* FTC_MruList; |
||||
|
||||
typedef struct FTC_MruListClassRec_ const * FTC_MruListClass; |
||||
|
||||
typedef FT_Int (*FTC_MruNode_CompareFunc)( FTC_MruNode node, |
||||
FT_Pointer key ); |
||||
|
||||
typedef FT_Error (*FTC_MruNode_InitFunc)( FTC_MruNode node, |
||||
FT_Pointer key, |
||||
FT_Pointer data ); |
||||
|
||||
typedef FT_Error (*FTC_MruNode_ResetFunc)( FTC_MruNode node, |
||||
FT_Pointer key, |
||||
FT_Pointer data ); |
||||
|
||||
typedef void (*FTC_MruNode_DoneFunc)( FTC_MruNode node, |
||||
FT_Pointer data ); |
||||
|
||||
typedef struct FTC_MruListClassRec_ |
||||
{ |
||||
FT_UInt node_size; |
||||
FTC_MruNode_CompareFunc node_compare; |
||||
FTC_MruNode_InitFunc node_init; |
||||
FTC_MruNode_ResetFunc node_reset; |
||||
FTC_MruNode_DoneFunc node_done; |
||||
|
||||
} FTC_MruListClassRec; |
||||
|
||||
typedef struct FTC_MruListRec_ |
||||
{ |
||||
FT_UInt num_nodes; |
||||
FT_UInt max_nodes; |
||||
FTC_MruNode nodes; |
||||
FT_Pointer data; |
||||
FTC_MruListClassRec clazz; |
||||
FT_Memory memory; |
||||
|
||||
} FTC_MruListRec; |
||||
|
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruList_Init( FTC_MruList list, |
||||
FTC_MruListClass clazz, |
||||
FT_UInt max_nodes, |
||||
FT_Pointer data, |
||||
FT_Memory memory ); |
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruList_Reset( FTC_MruList list ); |
||||
|
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruList_Done( FTC_MruList list ); |
||||
|
||||
FT_EXPORT( FTC_MruNode ) |
||||
FTC_MruList_Find( FTC_MruList list, |
||||
FT_Pointer key ); |
||||
|
||||
FT_EXPORT( FT_Error ) |
||||
FTC_MruList_New( FTC_MruList list, |
||||
FT_Pointer key, |
||||
FTC_MruNode *anode ); |
||||
|
||||
FT_EXPORT( FT_Error ) |
||||
FTC_MruList_Lookup( FTC_MruList list, |
||||
FT_Pointer key, |
||||
FTC_MruNode *pnode ); |
||||
|
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruList_Remove( FTC_MruList list, |
||||
FTC_MruNode node ); |
||||
|
||||
FT_EXPORT( void ) |
||||
FTC_MruList_RemoveSelection( FTC_MruList list, |
||||
FTC_MruNode_CompareFunc select, |
||||
FT_Pointer key ); |
||||
|
||||
|
||||
#ifdef FTC_INLINE |
||||
|
||||
#define FTC_MRULIST_LOOKUP( list, key, node, error ) \ |
||||
FT_BEGIN_STMNT \
|
||||
FTC_MruNode_CompareFunc _compare = (list)->clazz.node_compare; \
|
||||
FTC_MruNode _first, _node; \
|
||||
\
|
||||
error = 0; \
|
||||
_first = (list)->nodes; \
|
||||
_node = NULL; \
|
||||
\
|
||||
if ( _first ) \
|
||||
{ \
|
||||
_node = _first; \
|
||||
do \
|
||||
{ \
|
||||
if ( _compare( _node, (key) ) ) \
|
||||
{ \
|
||||
*(FTC_MruNode*)&(node) = _node; \
|
||||
goto _Ok; \
|
||||
} \
|
||||
_node = _node->next; \
|
||||
} \
|
||||
while ( _node != _first) ; \
|
||||
} \
|
||||
\
|
||||
error = FTC_MruList_New( (list), (key), (FTC_MruNode*)&(node) ); \
|
||||
_Ok: \
|
||||
; \
|
||||
FT_END_STMNT |
||||
|
||||
#else /* !FTC_INLINE */ |
||||
|
||||
#define FTC_MRULIST_LOOKUP_CMP( list, key, node, error ) \ |
||||
error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) )
|
||||
|
||||
#endif /* !FTC_INLINE */ |
||||
|
||||
|
||||
#define FTC_MRULIST_LOOP( list, node ) \ |
||||
FT_BEGIN_STMNT \
|
||||
FTC_MruNode _first = (list)->nodes; \
|
||||
\
|
||||
if ( _first ) \
|
||||
{ \
|
||||
FTC_MruNode _node = _first; \
|
||||
do \
|
||||
{ \
|
||||
*(FTC_MruNode*)&(node) = _node; |
||||
|
||||
|
||||
#define FTC_MRULIST_LOOP_END() \ |
||||
_node = _node->next; \
|
||||
} \
|
||||
while ( _node != _first ); \
|
||||
} \
|
||||
FT_END_STMNT |
||||
|
||||
/* */ |
||||
|
||||
FT_END_HEADER |
||||
|
||||
|
||||
#endif /* __FTCMRU_H__ */ |
||||
|
||||
|
||||
/* END */ |
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,393 +1,393 @@ |
||||
#include <ft2build.h> |
||||
#include FT_CACHE_H |
||||
#include FT_CACHE_INTERNAL_GLYPH_H |
||||
#include FT_CACHE_INTERNAL_IMAGE_H |
||||
#include FT_CACHE_INTERNAL_SBITS_H |
||||
#include FT_INTERNAL_MEMORY_H |
||||
|
||||
#include "ftcerror.h" |
||||
|
||||
|
||||
/*
|
||||
* Basic Families |
||||
* |
||||
* |
||||
*/ |
||||
typedef struct FTC_BasicAttrRec_ |
||||
{ |
||||
FTC_ScalerRec scaler; |
||||
FT_UInt load_flags; |
||||
|
||||
} FTC_BasicAttrRec, *FTC_BasicAttrs; |
||||
|
||||
#define FTC_BASIC_ATTR_COMPARE(a,b) \ |
||||
( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \
|
||||
(a)->load_flags == (b)->load_flags ) |
||||
|
||||
#define FTC_BASIC_ATTR_HASH(a) \ |
||||
( FTC_SCALER_HASH(&(a)->scaler) + 31*(a)->load_flags ) |
||||
|
||||
|
||||
typedef struct FTC_BasicQueryRec_ |
||||
{ |
||||
FTC_GQueryRec gquery; |
||||
FTC_BasicAttrRec attrs; |
||||
|
||||
} FTC_BasicQueryRec, *FTC_BasicQuery; |
||||
|
||||
|
||||
|
||||
typedef struct FTC_BasicFamilyRec_ |
||||
{ |
||||
FTC_FamilyRec family; |
||||
FTC_BasicAttrRec attrs; |
||||
|
||||
} FTC_BasicFamilyRec, *FTC_BasicFamily; |
||||
|
||||
|
||||
static FT_Bool |
||||
ftc_basic_family_compare( FTC_BasicFamily family, |
||||
FTC_BasicQuery query ) |
||||
{ |
||||
return FT_BOOL( FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs ) ); |
||||
} |
||||
|
||||
static FT_Error |
||||
ftc_basic_family_init( FTC_BasicFamily family, |
||||
FTC_BasicQuery query, |
||||
FTC_Cache cache ) |
||||
{ |
||||
FTC_Family_Init( FTC_FAMILY( family ), cache ); |
||||
family->attrs = query->attrs; |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
static FT_UInt |
||||
ftc_basic_family_get_count( FTC_BasicFamily family, |
||||
FTC_Manager manager ) |
||||
{ |
||||
FT_Error error; |
||||
FT_Face face; |
||||
FT_UInt result = 0; |
||||
|
||||
error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id, |
||||
&face ); |
||||
if ( !error ) |
||||
result = face->num_glyphs; |
||||
|
||||
return result; |
||||
} |
||||
|
||||
|
||||
static FT_Error |
||||
ftc_basic_family_load_bitmap( FTC_BasicFamily family, |
||||
FT_UInt gindex, |
||||
FTC_Manager manager, |
||||
FT_Face *aface ) |
||||
{ |
||||
FT_Error error; |
||||
FT_Size size; |
||||
|
||||
error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size ); |
||||
if ( !error ) |
||||
{ |
||||
FT_Face face = size->face; |
||||
|
||||
error = FT_Load_Glyph( face, gindex, family->attrs.load_flags | |
||||
FT_LOAD_RENDER ); |
||||
if ( !error ) |
||||
*aface = face; |
||||
} |
||||
return error; |
||||
} |
||||
|
||||
|
||||
static FT_Error |
||||
ftc_basic_family_load_glyph( FTC_BasicFamily family, |
||||
FT_UInt gindex, |
||||
FTC_Cache cache, |
||||
FT_Glyph *aglyph ) |
||||
{ |
||||
FT_Error error; |
||||
FTC_Scaler scaler = &family->attrs.scaler; |
||||
FT_Face face; |
||||
FT_Size size; |
||||
|
||||
/* we will now load the glyph image */ |
||||
error = FTC_Manager_LookupSize( cache->manager, |
||||
scaler, |
||||
&size ); |
||||
if ( !error ) |
||||
{ |
||||
face = size->face; |
||||
|
||||
error = FT_Load_Glyph( face, gindex, family->attrs.load_flags ); |
||||
if ( !error ) |
||||
{ |
||||
if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || |
||||
face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) |
||||
{ |
||||
/* ok, copy it */ |
||||
FT_Glyph glyph; |
||||
|
||||
|
||||
error = FT_Get_Glyph( face->glyph, &glyph ); |
||||
if ( !error ) |
||||
{ |
||||
*aglyph = glyph; |
||||
goto Exit; |
||||
} |
||||
} |
||||
else |
||||
error = FTC_Err_Invalid_Argument; |
||||
} |
||||
} |
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
|
||||
static FT_Bool |
||||
ftc_basic_gnode_compare_faceid( FTC_GNode gnode, |
||||
FTC_FaceID face_id, |
||||
FTC_Cache cache ) |
||||
{ |
||||
FTC_BasicFamily family = (FTC_BasicFamily) gnode->family; |
||||
FT_Bool result; |
||||
|
||||
result = FT_BOOL( family->attrs.scaler.face_id == face_id ); |
||||
if ( result ) |
||||
{ |
||||
/* we must call this function to avoid this node from appearing
|
||||
* in later lookups with the same face_id !! |
||||
*/ |
||||
FTC_GNode_UnselectFamily( gnode, cache ); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
|
||||
|
||||
/*
|
||||
* |
||||
* basic image cache |
||||
* |
||||
*/ |
||||
|
||||
static const FTC_IFamilyClassRec ftc_basic_image_family_class = |
||||
{ |
||||
{ |
||||
sizeof( FTC_BasicFamilyRec ), |
||||
(FTC_MruNode_CompareFunc) ftc_basic_family_compare, |
||||
(FTC_MruNode_InitFunc) ftc_basic_family_init, |
||||
(FTC_MruNode_ResetFunc) NULL, |
||||
(FTC_MruNode_DoneFunc) NULL |
||||
}, |
||||
(FTC_IFamily_LoadGlyphFunc) ftc_basic_family_load_glyph |
||||
}; |
||||
|
||||
|
||||
|
||||
static const FTC_GCacheClassRec ftc_basic_image_cache_class = |
||||
{ |
||||
{ |
||||
(FTC_Node_NewFunc) FTC_INode_New, |
||||
(FTC_Node_WeightFunc) FTC_INode_Weight, |
||||
(FTC_Node_CompareFunc) FTC_GNode_Compare, |
||||
(FTC_Node_CompareFunc) ftc_basic_gnode_compare_faceid, |
||||
(FTC_Node_FreeFunc) FTC_INode_Free, |
||||
|
||||
sizeof( FTC_GCacheRec ), |
||||
(FTC_Cache_InitFunc) FTC_GCache_Init, |
||||
(FTC_Cache_DoneFunc) FTC_GCache_Done |
||||
}, |
||||
(FTC_MruListClass) & ftc_basic_image_family_class |
||||
}; |
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_ImageCache_New( FTC_Manager manager, |
||||
FTC_ImageCache *acache ) |
||||
{ |
||||
return FTC_GCache_New( manager, & ftc_basic_image_cache_class, |
||||
(FTC_GCache*) acache ); |
||||
} |
||||
|
||||
|
||||
/* documentation is in ftcimage.h */ |
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_ImageCache_Lookup( FTC_ImageCache cache, |
||||
FTC_ImageType type, |
||||
FT_UInt gindex, |
||||
FT_Glyph *aglyph, |
||||
FTC_Node *anode ) |
||||
{ |
||||
FTC_BasicQueryRec query; |
||||
FTC_INode node; |
||||
FT_Error error; |
||||
FT_UInt32 hash; |
||||
|
||||
|
||||
/* some argument checks are delayed to FTC_Cache_Lookup */ |
||||
if ( !aglyph ) |
||||
{ |
||||
error = FTC_Err_Invalid_Argument; |
||||
goto Exit; |
||||
} |
||||
|
||||
*aglyph = NULL; |
||||
if ( anode ) |
||||
*anode = NULL; |
||||
|
||||
query.attrs.scaler.face_id = type->face_id; |
||||
query.attrs.scaler.width = type->width; |
||||
query.attrs.scaler.height = type->height; |
||||
query.attrs.scaler.pixel = 1; |
||||
query.attrs.load_flags = type->flags; |
||||
|
||||
hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex; |
||||
|
||||
#if 1 /* inlining is about 50% faster !! */ |
||||
FTC_GCACHE_LOOKUP_CMP( cache, |
||||
ftc_basic_family_compare, |
||||
FTC_GNode_Compare, |
||||
hash, gindex, |
||||
&query, |
||||
node, |
||||
error ); |
||||
#else |
||||
error = FTC_GCache_Lookup( FTC_GCACHE( cache ), |
||||
hash, gindex, |
||||
FTC_GQUERY( &query ), |
||||
(FTC_Node*) &node ); |
||||
#endif |
||||
if ( !error ) |
||||
{ |
||||
*aglyph = FTC_INODE(node)->glyph; |
||||
|
||||
if ( anode ) |
||||
{ |
||||
*anode = FTC_NODE(node); |
||||
FTC_NODE(node)->ref_count++; |
||||
} |
||||
} |
||||
|
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
|
||||
|
||||
/*
|
||||
* |
||||
* basic small bitmap cache |
||||
* |
||||
*/ |
||||
|
||||
|
||||
static const FTC_SFamilyClassRec ftc_basic_sbit_family_class = |
||||
{ |
||||
{ |
||||
sizeof( FTC_BasicFamilyRec ), |
||||
(FTC_MruNode_CompareFunc) ftc_basic_family_compare, |
||||
(FTC_MruNode_InitFunc) ftc_basic_family_init, |
||||
(FTC_MruNode_ResetFunc) NULL, |
||||
(FTC_MruNode_DoneFunc) NULL |
||||
}, |
||||
(FTC_SFamily_GetCountFunc) ftc_basic_family_get_count, |
||||
(FTC_SFamily_LoadGlyphFunc) ftc_basic_family_load_bitmap |
||||
}; |
||||
|
||||
|
||||
static const FTC_GCacheClassRec ftc_basic_sbit_cache_class = |
||||
{ |
||||
{ |
||||
(FTC_Node_NewFunc) FTC_SNode_New, |
||||
(FTC_Node_WeightFunc) FTC_SNode_Weight, |
||||
(FTC_Node_CompareFunc) FTC_SNode_Compare, |
||||
(FTC_Node_CompareFunc) ftc_basic_gnode_compare_faceid, |
||||
(FTC_Node_FreeFunc) FTC_SNode_Free, |
||||
|
||||
sizeof( FTC_GCacheRec ), |
||||
(FTC_Cache_InitFunc) FTC_GCache_Init, |
||||
(FTC_Cache_DoneFunc) FTC_GCache_Done |
||||
}, |
||||
(FTC_MruListClass) & ftc_basic_sbit_family_class |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_SBitCache_New( FTC_Manager manager, |
||||
FTC_SBitCache *acache ) |
||||
{ |
||||
return FTC_GCache_New( manager, & ftc_basic_sbit_cache_class, |
||||
(FTC_GCache*) acache ); |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_SBitCache_Lookup( FTC_SBitCache cache, |
||||
FTC_ImageType type, |
||||
FT_UInt gindex, |
||||
FTC_SBit *ansbit, |
||||
FTC_Node *anode ) |
||||
{ |
||||
FT_Error error; |
||||
FTC_BasicQueryRec query; |
||||
FTC_SNode node; |
||||
FT_UInt32 hash; |
||||
|
||||
if ( anode ) |
||||
*anode = NULL; |
||||
|
||||
/* other argument checks delayed to FTC_Cache_Lookup */ |
||||
if ( !ansbit ) |
||||
return FTC_Err_Invalid_Argument; |
||||
|
||||
*ansbit = NULL; |
||||
|
||||
query.attrs.scaler.face_id = type->face_id; |
||||
query.attrs.scaler.width = type->width; |
||||
query.attrs.scaler.height = type->height; |
||||
query.attrs.scaler.pixel = 1; |
||||
query.attrs.load_flags = type->flags; |
||||
|
||||
/* beware, the hash must be the same for all glyph ranges !!
|
||||
*/ |
||||
hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + |
||||
(gindex/FTC_SBIT_ITEMS_PER_NODE); |
||||
|
||||
#if 1 /* inlining is about 50% faster !! */ |
||||
FTC_GCACHE_LOOKUP_CMP( cache, |
||||
ftc_basic_family_compare, |
||||
FTC_SNode_Compare, |
||||
hash, gindex, |
||||
&query, |
||||
node, |
||||
error ); |
||||
#else |
||||
error = FTC_GCache_Lookup( FTC_GCACHE( cache ), |
||||
hash, |
||||
gindex, |
||||
FTC_GQUERY( &query ), |
||||
(FTC_Node*) &node ); |
||||
#endif |
||||
if ( error ) |
||||
goto Exit; |
||||
|
||||
*ansbit = node->sbits + ( gindex - FTC_GNODE(node)->gindex ); |
||||
|
||||
if ( anode ) |
||||
{ |
||||
*anode = FTC_NODE( node ); |
||||
FTC_NODE( node )->ref_count++; |
||||
} |
||||
|
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
#include <ft2build.h> |
||||
#include FT_CACHE_H |
||||
#include FT_CACHE_INTERNAL_GLYPH_H |
||||
#include FT_CACHE_INTERNAL_IMAGE_H |
||||
#include FT_CACHE_INTERNAL_SBITS_H |
||||
#include FT_INTERNAL_MEMORY_H |
||||
|
||||
#include "ftcerror.h" |
||||
|
||||
|
||||
/*
|
||||
* Basic Families |
||||
* |
||||
* |
||||
*/ |
||||
typedef struct FTC_BasicAttrRec_ |
||||
{ |
||||
FTC_ScalerRec scaler; |
||||
FT_UInt load_flags; |
||||
|
||||
} FTC_BasicAttrRec, *FTC_BasicAttrs; |
||||
|
||||
#define FTC_BASIC_ATTR_COMPARE(a,b) \ |
||||
( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \
|
||||
(a)->load_flags == (b)->load_flags ) |
||||
|
||||
#define FTC_BASIC_ATTR_HASH(a) \ |
||||
( FTC_SCALER_HASH(&(a)->scaler) + 31*(a)->load_flags ) |
||||
|
||||
|
||||
typedef struct FTC_BasicQueryRec_ |
||||
{ |
||||
FTC_GQueryRec gquery; |
||||
FTC_BasicAttrRec attrs; |
||||
|
||||
} FTC_BasicQueryRec, *FTC_BasicQuery; |
||||
|
||||
|
||||
|
||||
typedef struct FTC_BasicFamilyRec_ |
||||
{ |
||||
FTC_FamilyRec family; |
||||
FTC_BasicAttrRec attrs; |
||||
|
||||
} FTC_BasicFamilyRec, *FTC_BasicFamily; |
||||
|
||||
|
||||
static FT_Bool |
||||
ftc_basic_family_compare( FTC_BasicFamily family, |
||||
FTC_BasicQuery query ) |
||||
{ |
||||
return FT_BOOL( FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs ) ); |
||||
} |
||||
|
||||
static FT_Error |
||||
ftc_basic_family_init( FTC_BasicFamily family, |
||||
FTC_BasicQuery query, |
||||
FTC_Cache cache ) |
||||
{ |
||||
FTC_Family_Init( FTC_FAMILY( family ), cache ); |
||||
family->attrs = query->attrs; |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
static FT_UInt |
||||
ftc_basic_family_get_count( FTC_BasicFamily family, |
||||
FTC_Manager manager ) |
||||
{ |
||||
FT_Error error; |
||||
FT_Face face; |
||||
FT_UInt result = 0; |
||||
|
||||
error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id, |
||||
&face ); |
||||
if ( !error ) |
||||
result = face->num_glyphs; |
||||
|
||||
return result; |
||||
} |
||||
|
||||
|
||||
static FT_Error |
||||
ftc_basic_family_load_bitmap( FTC_BasicFamily family, |
||||
FT_UInt gindex, |
||||
FTC_Manager manager, |
||||
FT_Face *aface ) |
||||
{ |
||||
FT_Error error; |
||||
FT_Size size; |
||||
|
||||
error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size ); |
||||
if ( !error ) |
||||
{ |
||||
FT_Face face = size->face; |
||||
|
||||
error = FT_Load_Glyph( face, gindex, family->attrs.load_flags | |
||||
FT_LOAD_RENDER ); |
||||
if ( !error ) |
||||
*aface = face; |
||||
} |
||||
return error; |
||||
} |
||||
|
||||
|
||||
static FT_Error |
||||
ftc_basic_family_load_glyph( FTC_BasicFamily family, |
||||
FT_UInt gindex, |
||||
FTC_Cache cache, |
||||
FT_Glyph *aglyph ) |
||||
{ |
||||
FT_Error error; |
||||
FTC_Scaler scaler = &family->attrs.scaler; |
||||
FT_Face face; |
||||
FT_Size size; |
||||
|
||||
/* we will now load the glyph image */ |
||||
error = FTC_Manager_LookupSize( cache->manager, |
||||
scaler, |
||||
&size ); |
||||
if ( !error ) |
||||
{ |
||||
face = size->face; |
||||
|
||||
error = FT_Load_Glyph( face, gindex, family->attrs.load_flags ); |
||||
if ( !error ) |
||||
{ |
||||
if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || |
||||
face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) |
||||
{ |
||||
/* ok, copy it */ |
||||
FT_Glyph glyph; |
||||
|
||||
|
||||
error = FT_Get_Glyph( face->glyph, &glyph ); |
||||
if ( !error ) |
||||
{ |
||||
*aglyph = glyph; |
||||
goto Exit; |
||||
} |
||||
} |
||||
else |
||||
error = FTC_Err_Invalid_Argument; |
||||
} |
||||
} |
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
|
||||
static FT_Bool |
||||
ftc_basic_gnode_compare_faceid( FTC_GNode gnode, |
||||
FTC_FaceID face_id, |
||||
FTC_Cache cache ) |
||||
{ |
||||
FTC_BasicFamily family = (FTC_BasicFamily) gnode->family; |
||||
FT_Bool result; |
||||
|
||||
result = FT_BOOL( family->attrs.scaler.face_id == face_id ); |
||||
if ( result ) |
||||
{ |
||||
/* we must call this function to avoid this node from appearing
|
||||
* in later lookups with the same face_id !! |
||||
*/ |
||||
FTC_GNode_UnselectFamily( gnode, cache ); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
|
||||
|
||||
/*
|
||||
* |
||||
* basic image cache |
||||
* |
||||
*/ |
||||
|
||||
static const FTC_IFamilyClassRec ftc_basic_image_family_class = |
||||
{ |
||||
{ |
||||
sizeof( FTC_BasicFamilyRec ), |
||||
(FTC_MruNode_CompareFunc) ftc_basic_family_compare, |
||||
(FTC_MruNode_InitFunc) ftc_basic_family_init, |
||||
(FTC_MruNode_ResetFunc) NULL, |
||||
(FTC_MruNode_DoneFunc) NULL |
||||
}, |
||||
(FTC_IFamily_LoadGlyphFunc) ftc_basic_family_load_glyph |
||||
}; |
||||
|
||||
|
||||
|
||||
static const FTC_GCacheClassRec ftc_basic_image_cache_class = |
||||
{ |
||||
{ |
||||
(FTC_Node_NewFunc) FTC_INode_New, |
||||
(FTC_Node_WeightFunc) FTC_INode_Weight, |
||||
(FTC_Node_CompareFunc) FTC_GNode_Compare, |
||||
(FTC_Node_CompareFunc) ftc_basic_gnode_compare_faceid, |
||||
(FTC_Node_FreeFunc) FTC_INode_Free, |
||||
|
||||
sizeof( FTC_GCacheRec ), |
||||
(FTC_Cache_InitFunc) FTC_GCache_Init, |
||||
(FTC_Cache_DoneFunc) FTC_GCache_Done |
||||
}, |
||||
(FTC_MruListClass) & ftc_basic_image_family_class |
||||
}; |
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_ImageCache_New( FTC_Manager manager, |
||||
FTC_ImageCache *acache ) |
||||
{ |
||||
return FTC_GCache_New( manager, & ftc_basic_image_cache_class, |
||||
(FTC_GCache*) acache ); |
||||
} |
||||
|
||||
|
||||
/* documentation is in ftcimage.h */ |
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_ImageCache_Lookup( FTC_ImageCache cache, |
||||
FTC_ImageType type, |
||||
FT_UInt gindex, |
||||
FT_Glyph *aglyph, |
||||
FTC_Node *anode ) |
||||
{ |
||||
FTC_BasicQueryRec query; |
||||
FTC_INode node; |
||||
FT_Error error; |
||||
FT_UInt32 hash; |
||||
|
||||
|
||||
/* some argument checks are delayed to FTC_Cache_Lookup */ |
||||
if ( !aglyph ) |
||||
{ |
||||
error = FTC_Err_Invalid_Argument; |
||||
goto Exit; |
||||
} |
||||
|
||||
*aglyph = NULL; |
||||
if ( anode ) |
||||
*anode = NULL; |
||||
|
||||
query.attrs.scaler.face_id = type->face_id; |
||||
query.attrs.scaler.width = type->width; |
||||
query.attrs.scaler.height = type->height; |
||||
query.attrs.scaler.pixel = 1; |
||||
query.attrs.load_flags = type->flags; |
||||
|
||||
hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex; |
||||
|
||||
#if 1 /* inlining is about 50% faster !! */ |
||||
FTC_GCACHE_LOOKUP_CMP( cache, |
||||
ftc_basic_family_compare, |
||||
FTC_GNode_Compare, |
||||
hash, gindex, |
||||
&query, |
||||
node, |
||||
error ); |
||||
#else |
||||
error = FTC_GCache_Lookup( FTC_GCACHE( cache ), |
||||
hash, gindex, |
||||
FTC_GQUERY( &query ), |
||||
(FTC_Node*) &node ); |
||||
#endif |
||||
if ( !error ) |
||||
{ |
||||
*aglyph = FTC_INODE(node)->glyph; |
||||
|
||||
if ( anode ) |
||||
{ |
||||
*anode = FTC_NODE(node); |
||||
FTC_NODE(node)->ref_count++; |
||||
} |
||||
} |
||||
|
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
|
||||
|
||||
/*
|
||||
* |
||||
* basic small bitmap cache |
||||
* |
||||
*/ |
||||
|
||||
|
||||
static const FTC_SFamilyClassRec ftc_basic_sbit_family_class = |
||||
{ |
||||
{ |
||||
sizeof( FTC_BasicFamilyRec ), |
||||
(FTC_MruNode_CompareFunc) ftc_basic_family_compare, |
||||
(FTC_MruNode_InitFunc) ftc_basic_family_init, |
||||
(FTC_MruNode_ResetFunc) NULL, |
||||
(FTC_MruNode_DoneFunc) NULL |
||||
}, |
||||
(FTC_SFamily_GetCountFunc) ftc_basic_family_get_count, |
||||
(FTC_SFamily_LoadGlyphFunc) ftc_basic_family_load_bitmap |
||||
}; |
||||
|
||||
|
||||
static const FTC_GCacheClassRec ftc_basic_sbit_cache_class = |
||||
{ |
||||
{ |
||||
(FTC_Node_NewFunc) FTC_SNode_New, |
||||
(FTC_Node_WeightFunc) FTC_SNode_Weight, |
||||
(FTC_Node_CompareFunc) FTC_SNode_Compare, |
||||
(FTC_Node_CompareFunc) ftc_basic_gnode_compare_faceid, |
||||
(FTC_Node_FreeFunc) FTC_SNode_Free, |
||||
|
||||
sizeof( FTC_GCacheRec ), |
||||
(FTC_Cache_InitFunc) FTC_GCache_Init, |
||||
(FTC_Cache_DoneFunc) FTC_GCache_Done |
||||
}, |
||||
(FTC_MruListClass) & ftc_basic_sbit_family_class |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_SBitCache_New( FTC_Manager manager, |
||||
FTC_SBitCache *acache ) |
||||
{ |
||||
return FTC_GCache_New( manager, & ftc_basic_sbit_cache_class, |
||||
(FTC_GCache*) acache ); |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_SBitCache_Lookup( FTC_SBitCache cache, |
||||
FTC_ImageType type, |
||||
FT_UInt gindex, |
||||
FTC_SBit *ansbit, |
||||
FTC_Node *anode ) |
||||
{ |
||||
FT_Error error; |
||||
FTC_BasicQueryRec query; |
||||
FTC_SNode node; |
||||
FT_UInt32 hash; |
||||
|
||||
if ( anode ) |
||||
*anode = NULL; |
||||
|
||||
/* other argument checks delayed to FTC_Cache_Lookup */ |
||||
if ( !ansbit ) |
||||
return FTC_Err_Invalid_Argument; |
||||
|
||||
*ansbit = NULL; |
||||
|
||||
query.attrs.scaler.face_id = type->face_id; |
||||
query.attrs.scaler.width = type->width; |
||||
query.attrs.scaler.height = type->height; |
||||
query.attrs.scaler.pixel = 1; |
||||
query.attrs.load_flags = type->flags; |
||||
|
||||
/* beware, the hash must be the same for all glyph ranges !!
|
||||
*/ |
||||
hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + |
||||
(gindex/FTC_SBIT_ITEMS_PER_NODE); |
||||
|
||||
#if 1 /* inlining is about 50% faster !! */ |
||||
FTC_GCACHE_LOOKUP_CMP( cache, |
||||
ftc_basic_family_compare, |
||||
FTC_SNode_Compare, |
||||
hash, gindex, |
||||
&query, |
||||
node, |
||||
error ); |
||||
#else |
||||
error = FTC_GCache_Lookup( FTC_GCACHE( cache ), |
||||
hash, |
||||
gindex, |
||||
FTC_GQUERY( &query ), |
||||
(FTC_Node*) &node ); |
||||
#endif |
||||
if ( error ) |
||||
goto Exit; |
||||
|
||||
*ansbit = node->sbits + ( gindex - FTC_GNODE(node)->gindex ); |
||||
|
||||
if ( anode ) |
||||
{ |
||||
*anode = FTC_NODE( node ); |
||||
FTC_NODE( node )->ref_count++; |
||||
} |
||||
|
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,271 +1,271 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ftccmap.c */ |
||||
/* */ |
||||
/* FreeType CharMap cache (body) */ |
||||
/* */ |
||||
/* Copyright 2000-2001, 2002, 2003 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used, */ |
||||
/* modified, and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#include <ft2build.h> |
||||
#include FT_FREETYPE_H |
||||
#include FT_CACHE_H |
||||
#include FT_CACHE_INTERNAL_MANAGER_H |
||||
#include FT_INTERNAL_MEMORY_H |
||||
#include FT_INTERNAL_DEBUG_H |
||||
#include FT_TRUETYPE_IDS_H |
||||
|
||||
#include "ftcerror.h" |
||||
|
||||
#undef FT_COMPONENT |
||||
#define FT_COMPONENT trace_cache |
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* Each FTC_CMapNode contains a simple array to map a range of character */ |
||||
/* codes to equivalent glyph indices. */ |
||||
/* */ |
||||
/* For now, the implementation is very basic: Each node maps a range of */ |
||||
/* 128 consecutive character codes to their corresponding glyph indices. */ |
||||
/* */ |
||||
/* We could do more complex things, but I don't think it is really very */ |
||||
/* useful. */ |
||||
/* */ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
/* number of glyph indices / character code per node */ |
||||
#define FTC_CMAP_INDICES_MAX 128 |
||||
|
||||
/* compute a query/node hash */ |
||||
#define FTC_CMAP_HASH( faceid, index, charcode ) \ |
||||
( FTC_FACE_ID_HASH( faceid ) + 211*( index ) + ((char_code) / FTC_CMAP_INDICES_MAX) ) |
||||
|
||||
/* the charmap query */ |
||||
typedef struct FTC_CMapQueryRec_ |
||||
{ |
||||
FTC_FaceID face_id; |
||||
FT_UInt cmap_index; |
||||
FT_UInt32 char_code; |
||||
|
||||
} FTC_CMapQueryRec, *FTC_CMapQuery; |
||||
|
||||
#define FTC_CMAP_QUERY(x) ((FTC_CMapQuery)(x)) |
||||
#define FTC_CMAP_QUERY_HASH(x) FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code ) |
||||
|
||||
/* the cmap cache node */ |
||||
typedef struct FTC_CMapNodeRec_ |
||||
{ |
||||
FTC_NodeRec node; |
||||
FTC_FaceID face_id; |
||||
FT_UInt cmap_index; |
||||
FT_UInt32 first; /* first character in node */ |
||||
FT_UInt16 indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices */ |
||||
|
||||
} FTC_CMapNodeRec, *FTC_CMapNode; |
||||
|
||||
#define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) ) |
||||
#define FTC_CMAP_NODE_HASH(x) FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first ) |
||||
|
||||
/* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */ |
||||
/* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */ |
||||
#define FTC_CMAP_UNKNOWN ( (FT_UInt16)-1 ) |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/***** *****/ |
||||
/***** CHARMAP NODES *****/ |
||||
/***** *****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
/* no need for specific finalizer; we use "ftc_node_done" directly */ |
||||
|
||||
FT_CALLBACK_DEF( void ) |
||||
ftc_cmap_node_free( FTC_CMapNode node, |
||||
FTC_Cache cache ) |
||||
{ |
||||
FT_Memory memory = cache->memory; |
||||
|
||||
FT_FREE( node ); |
||||
} |
||||
|
||||
|
||||
/* initialize a new cmap node */ |
||||
FT_CALLBACK_DEF( FT_Error ) |
||||
ftc_cmap_node_new( FTC_CMapNode *anode, |
||||
FTC_CMapQuery query, |
||||
FTC_Cache cache ) |
||||
{ |
||||
FT_Error error; |
||||
FT_Memory memory = cache->memory; |
||||
FTC_CMapNode node; |
||||
FT_UInt nn; |
||||
|
||||
if ( !FT_NEW( node ) ) |
||||
{ |
||||
node->face_id = query->face_id; |
||||
node->cmap_index = query->cmap_index; |
||||
node->first = (query->char_code / FTC_CMAP_INDICES_MAX) * |
||||
FTC_CMAP_INDICES_MAX; |
||||
|
||||
for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ ) |
||||
node->indices[nn] = FTC_CMAP_UNKNOWN; |
||||
} |
||||
|
||||
*anode = node; |
||||
return error; |
||||
} |
||||
|
||||
|
||||
/* compute the weight of a given cmap node */ |
||||
FT_CALLBACK_DEF( FT_ULong ) |
||||
ftc_cmap_node_weight( FTC_CMapNode cnode ) |
||||
{ |
||||
FT_UNUSED( cnode ); |
||||
|
||||
return sizeof ( *cnode ); |
||||
} |
||||
|
||||
|
||||
/* compare a cmap node to a given query */ |
||||
FT_CALLBACK_DEF( FT_Bool ) |
||||
ftc_cmap_node_compare( FTC_CMapNode node, |
||||
FTC_CMapQuery query ) |
||||
{ |
||||
if ( node->face_id == query->face_id && |
||||
node->cmap_index == query->cmap_index ) |
||||
{ |
||||
FT_UInt32 offset = (FT_UInt32)( query->char_code - node->first ); |
||||
|
||||
return FT_BOOL( offset < FTC_CMAP_INDICES_MAX ); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Bool ) |
||||
ftc_cmap_node_remove_faceid( FTC_CMapNode node, |
||||
FTC_FaceID face_id ) |
||||
{ |
||||
return FT_BOOL( node->face_id == face_id ); |
||||
} |
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/***** *****/ |
||||
/***** GLYPH IMAGE CACHE *****/ |
||||
/***** *****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF |
||||
const FTC_CacheClassRec ftc_cmap_cache_class = |
||||
{ |
||||
(FTC_Node_NewFunc) ftc_cmap_node_new, |
||||
(FTC_Node_WeightFunc) ftc_cmap_node_weight, |
||||
(FTC_Node_CompareFunc) ftc_cmap_node_compare, |
||||
(FTC_Node_CompareFunc) ftc_cmap_node_remove_faceid, |
||||
(FTC_Node_FreeFunc) ftc_cmap_node_free, |
||||
|
||||
sizeof ( FTC_CacheRec ), |
||||
(FTC_Cache_InitFunc) FTC_Cache_Init, |
||||
(FTC_Cache_DoneFunc) FTC_Cache_Done, |
||||
}; |
||||
|
||||
/* documentation is in ftccmap.h */ |
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_CMapCache_New( FTC_Manager manager, |
||||
FTC_CMapCache *acache ) |
||||
{ |
||||
return FTC_Manager_RegisterCache( manager, |
||||
& ftc_cmap_cache_class, |
||||
FTC_CACHE_P( acache ) ); |
||||
} |
||||
/* documentation is in ftccmap.h */ |
||||
|
||||
FT_EXPORT_DEF( FT_UInt ) |
||||
FTC_CMapCache_Lookup( FTC_CMapCache cmap_cache, |
||||
FTC_FaceID face_id, |
||||
FT_Int cmap_index, |
||||
FT_UInt32 char_code ) |
||||
{ |
||||
FTC_Cache cache = FTC_CACHE( cmap_cache ); |
||||
FTC_CMapQueryRec query; |
||||
FTC_CMapNode node; |
||||
FT_Error error; |
||||
FT_UInt gindex = 0; |
||||
FT_UInt32 hash; |
||||
|
||||
|
||||
if ( !cache ) |
||||
{ |
||||
FT_ERROR(( "FTC_CMapCache_Lookup: bad arguments, returning 0!\n" )); |
||||
return 0; |
||||
} |
||||
|
||||
query.face_id = face_id; |
||||
query.cmap_index = (FT_UInt)cmap_index; |
||||
query.char_code = char_code; |
||||
|
||||
hash = FTC_CMAP_HASH( face_id, cmap_index, char_code ); |
||||
|
||||
#if 1 |
||||
FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, |
||||
node, error ); |
||||
#else |
||||
error = FTC_Cache_Lookup( cache, hash, &query, (FTC_Node*) &node ); |
||||
#endif |
||||
if ( error ) |
||||
goto Exit; |
||||
|
||||
FT_ASSERT( (FT_UInt)( char_code - node->first ) < FTC_CMAP_INDICES_MAX ); |
||||
|
||||
gindex = node->indices[ char_code - node->first ]; |
||||
if ( gindex == FTC_CMAP_UNKNOWN ) |
||||
{ |
||||
FT_Face face; |
||||
|
||||
gindex = 0; |
||||
|
||||
error = FTC_Manager_LookupFace( cache->manager, node->face_id, &face ); |
||||
if ( error ) |
||||
goto Exit; |
||||
|
||||
if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps ) |
||||
{ |
||||
FT_CharMap old, cmap = NULL; |
||||
|
||||
old = face->charmap; |
||||
cmap = face->charmaps[ cmap_index ]; |
||||
|
||||
if (old != cmap) |
||||
FT_Set_Charmap( face, cmap ); |
||||
|
||||
gindex = FT_Get_Char_Index( face, char_code ); |
||||
|
||||
if (old != cmap) |
||||
FT_Set_Charmap( face, old ); |
||||
} |
||||
|
||||
node->indices[ char_code - node->first ] = gindex; |
||||
} |
||||
|
||||
Exit: |
||||
return gindex; |
||||
} |
||||
|
||||
/* END */ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ftccmap.c */ |
||||
/* */ |
||||
/* FreeType CharMap cache (body) */ |
||||
/* */ |
||||
/* Copyright 2000-2001, 2002, 2003 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used, */ |
||||
/* modified, and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#include <ft2build.h> |
||||
#include FT_FREETYPE_H |
||||
#include FT_CACHE_H |
||||
#include FT_CACHE_INTERNAL_MANAGER_H |
||||
#include FT_INTERNAL_MEMORY_H |
||||
#include FT_INTERNAL_DEBUG_H |
||||
#include FT_TRUETYPE_IDS_H |
||||
|
||||
#include "ftcerror.h" |
||||
|
||||
#undef FT_COMPONENT |
||||
#define FT_COMPONENT trace_cache |
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* Each FTC_CMapNode contains a simple array to map a range of character */ |
||||
/* codes to equivalent glyph indices. */ |
||||
/* */ |
||||
/* For now, the implementation is very basic: Each node maps a range of */ |
||||
/* 128 consecutive character codes to their corresponding glyph indices. */ |
||||
/* */ |
||||
/* We could do more complex things, but I don't think it is really very */ |
||||
/* useful. */ |
||||
/* */ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
/* number of glyph indices / character code per node */ |
||||
#define FTC_CMAP_INDICES_MAX 128 |
||||
|
||||
/* compute a query/node hash */ |
||||
#define FTC_CMAP_HASH( faceid, index, charcode ) \ |
||||
( FTC_FACE_ID_HASH( faceid ) + 211*( index ) + ((char_code) / FTC_CMAP_INDICES_MAX) ) |
||||
|
||||
/* the charmap query */ |
||||
typedef struct FTC_CMapQueryRec_ |
||||
{ |
||||
FTC_FaceID face_id; |
||||
FT_UInt cmap_index; |
||||
FT_UInt32 char_code; |
||||
|
||||
} FTC_CMapQueryRec, *FTC_CMapQuery; |
||||
|
||||
#define FTC_CMAP_QUERY(x) ((FTC_CMapQuery)(x)) |
||||
#define FTC_CMAP_QUERY_HASH(x) FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code ) |
||||
|
||||
/* the cmap cache node */ |
||||
typedef struct FTC_CMapNodeRec_ |
||||
{ |
||||
FTC_NodeRec node; |
||||
FTC_FaceID face_id; |
||||
FT_UInt cmap_index; |
||||
FT_UInt32 first; /* first character in node */ |
||||
FT_UInt16 indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices */ |
||||
|
||||
} FTC_CMapNodeRec, *FTC_CMapNode; |
||||
|
||||
#define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) ) |
||||
#define FTC_CMAP_NODE_HASH(x) FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first ) |
||||
|
||||
/* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */ |
||||
/* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */ |
||||
#define FTC_CMAP_UNKNOWN ( (FT_UInt16)-1 ) |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/***** *****/ |
||||
/***** CHARMAP NODES *****/ |
||||
/***** *****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
/* no need for specific finalizer; we use "ftc_node_done" directly */ |
||||
|
||||
FT_CALLBACK_DEF( void ) |
||||
ftc_cmap_node_free( FTC_CMapNode node, |
||||
FTC_Cache cache ) |
||||
{ |
||||
FT_Memory memory = cache->memory; |
||||
|
||||
FT_FREE( node ); |
||||
} |
||||
|
||||
|
||||
/* initialize a new cmap node */ |
||||
FT_CALLBACK_DEF( FT_Error ) |
||||
ftc_cmap_node_new( FTC_CMapNode *anode, |
||||
FTC_CMapQuery query, |
||||
FTC_Cache cache ) |
||||
{ |
||||
FT_Error error; |
||||
FT_Memory memory = cache->memory; |
||||
FTC_CMapNode node; |
||||
FT_UInt nn; |
||||
|
||||
if ( !FT_NEW( node ) ) |
||||
{ |
||||
node->face_id = query->face_id; |
||||
node->cmap_index = query->cmap_index; |
||||
node->first = (query->char_code / FTC_CMAP_INDICES_MAX) * |
||||
FTC_CMAP_INDICES_MAX; |
||||
|
||||
for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ ) |
||||
node->indices[nn] = FTC_CMAP_UNKNOWN; |
||||
} |
||||
|
||||
*anode = node; |
||||
return error; |
||||
} |
||||
|
||||
|
||||
/* compute the weight of a given cmap node */ |
||||
FT_CALLBACK_DEF( FT_ULong ) |
||||
ftc_cmap_node_weight( FTC_CMapNode cnode ) |
||||
{ |
||||
FT_UNUSED( cnode ); |
||||
|
||||
return sizeof ( *cnode ); |
||||
} |
||||
|
||||
|
||||
/* compare a cmap node to a given query */ |
||||
FT_CALLBACK_DEF( FT_Bool ) |
||||
ftc_cmap_node_compare( FTC_CMapNode node, |
||||
FTC_CMapQuery query ) |
||||
{ |
||||
if ( node->face_id == query->face_id && |
||||
node->cmap_index == query->cmap_index ) |
||||
{ |
||||
FT_UInt32 offset = (FT_UInt32)( query->char_code - node->first ); |
||||
|
||||
return FT_BOOL( offset < FTC_CMAP_INDICES_MAX ); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Bool ) |
||||
ftc_cmap_node_remove_faceid( FTC_CMapNode node, |
||||
FTC_FaceID face_id ) |
||||
{ |
||||
return FT_BOOL( node->face_id == face_id ); |
||||
} |
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/***** *****/ |
||||
/***** GLYPH IMAGE CACHE *****/ |
||||
/***** *****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF |
||||
const FTC_CacheClassRec ftc_cmap_cache_class = |
||||
{ |
||||
(FTC_Node_NewFunc) ftc_cmap_node_new, |
||||
(FTC_Node_WeightFunc) ftc_cmap_node_weight, |
||||
(FTC_Node_CompareFunc) ftc_cmap_node_compare, |
||||
(FTC_Node_CompareFunc) ftc_cmap_node_remove_faceid, |
||||
(FTC_Node_FreeFunc) ftc_cmap_node_free, |
||||
|
||||
sizeof ( FTC_CacheRec ), |
||||
(FTC_Cache_InitFunc) FTC_Cache_Init, |
||||
(FTC_Cache_DoneFunc) FTC_Cache_Done, |
||||
}; |
||||
|
||||
/* documentation is in ftccmap.h */ |
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_CMapCache_New( FTC_Manager manager, |
||||
FTC_CMapCache *acache ) |
||||
{ |
||||
return FTC_Manager_RegisterCache( manager, |
||||
& ftc_cmap_cache_class, |
||||
FTC_CACHE_P( acache ) ); |
||||
} |
||||
/* documentation is in ftccmap.h */ |
||||
|
||||
FT_EXPORT_DEF( FT_UInt ) |
||||
FTC_CMapCache_Lookup( FTC_CMapCache cmap_cache, |
||||
FTC_FaceID face_id, |
||||
FT_Int cmap_index, |
||||
FT_UInt32 char_code ) |
||||
{ |
||||
FTC_Cache cache = FTC_CACHE( cmap_cache ); |
||||
FTC_CMapQueryRec query; |
||||
FTC_CMapNode node; |
||||
FT_Error error; |
||||
FT_UInt gindex = 0; |
||||
FT_UInt32 hash; |
||||
|
||||
|
||||
if ( !cache ) |
||||
{ |
||||
FT_ERROR(( "FTC_CMapCache_Lookup: bad arguments, returning 0!\n" )); |
||||
return 0; |
||||
} |
||||
|
||||
query.face_id = face_id; |
||||
query.cmap_index = (FT_UInt)cmap_index; |
||||
query.char_code = char_code; |
||||
|
||||
hash = FTC_CMAP_HASH( face_id, cmap_index, char_code ); |
||||
|
||||
#if 1 |
||||
FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, |
||||
node, error ); |
||||
#else |
||||
error = FTC_Cache_Lookup( cache, hash, &query, (FTC_Node*) &node ); |
||||
#endif |
||||
if ( error ) |
||||
goto Exit; |
||||
|
||||
FT_ASSERT( (FT_UInt)( char_code - node->first ) < FTC_CMAP_INDICES_MAX ); |
||||
|
||||
gindex = node->indices[ char_code - node->first ]; |
||||
if ( gindex == FTC_CMAP_UNKNOWN ) |
||||
{ |
||||
FT_Face face; |
||||
|
||||
gindex = 0; |
||||
|
||||
error = FTC_Manager_LookupFace( cache->manager, node->face_id, &face ); |
||||
if ( error ) |
||||
goto Exit; |
||||
|
||||
if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps ) |
||||
{ |
||||
FT_CharMap old, cmap = NULL; |
||||
|
||||
old = face->charmap; |
||||
cmap = face->charmaps[ cmap_index ]; |
||||
|
||||
if (old != cmap) |
||||
FT_Set_Charmap( face, cmap ); |
||||
|
||||
gindex = FT_Get_Char_Index( face, char_code ); |
||||
|
||||
if (old != cmap) |
||||
FT_Set_Charmap( face, old ); |
||||
} |
||||
|
||||
node->indices[ char_code - node->first ] = gindex; |
||||
} |
||||
|
||||
Exit: |
||||
return gindex; |
||||
} |
||||
|
||||
/* END */ |
||||
|
@ -1,152 +1,152 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ftcglyph.c */ |
||||
/* */ |
||||
/* FreeType Glyph Image (FT_Glyph) cache (body). */ |
||||
/* */ |
||||
/* 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. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#include <ft2build.h> |
||||
#include FT_CACHE_H |
||||
#include FT_CACHE_INTERNAL_GLYPH_H |
||||
#include FT_ERRORS_H |
||||
#include FT_INTERNAL_OBJECTS_H |
||||
#include FT_INTERNAL_DEBUG_H |
||||
|
||||
#include "ftcerror.h" |
||||
|
||||
|
||||
/* create a new chunk node, setting its cache index and ref count */ |
||||
FT_EXPORT_DEF( void ) |
||||
FTC_GNode_Init( FTC_GNode gnode, |
||||
FT_UInt gindex, |
||||
FTC_Family family ) |
||||
{ |
||||
gnode->family = family; |
||||
gnode->gindex = gindex; |
||||
family->num_nodes++; |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( void ) |
||||
FTC_GNode_UnselectFamily( FTC_GNode gnode, |
||||
FTC_Cache cache ) |
||||
{ |
||||
FTC_Family family = gnode->family; |
||||
|
||||
gnode->family = NULL; |
||||
if ( family && --family->num_nodes <= 0 ) |
||||
{ |
||||
FTC_MruList_Remove( & FTC_GCACHE(cache)->families, (FTC_MruNode)family ); |
||||
} |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( void ) |
||||
FTC_GNode_Done( FTC_GNode gnode, |
||||
FTC_Cache cache ) |
||||
{ |
||||
/* finalize the node */ |
||||
gnode->gindex = 0; |
||||
|
||||
FTC_GNode_UnselectFamily( gnode, cache ); |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Bool ) |
||||
FTC_GNode_Compare( FTC_GNode gnode, |
||||
FTC_GQuery gquery ) |
||||
{ |
||||
return FT_BOOL( gnode->family == gquery->family && |
||||
gnode->gindex == gquery->gindex ); |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/***** *****/ |
||||
/***** CHUNK SETS *****/ |
||||
/***** *****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
FT_EXPORT_DEF( void ) |
||||
FTC_Family_Init( FTC_Family family, |
||||
FTC_Cache cache ) |
||||
{ |
||||
FTC_GCacheClass clazz = FTC_CACHE__GCACHE_CLASS(cache); |
||||
|
||||
family->clazz = clazz->family_class; |
||||
family->num_nodes = 0; |
||||
family->cache = cache; |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_GCache_Init( FTC_GCache cache ) |
||||
{ |
||||
FT_Error error; |
||||
|
||||
error = FTC_Cache_Init( FTC_CACHE(cache) ); |
||||
if ( !error ) |
||||
{ |
||||
FTC_GCacheClass clazz = (FTC_GCacheClass) FTC_CACHE(cache)->org_class; |
||||
|
||||
FTC_MruList_Init( &cache->families, |
||||
clazz->family_class, |
||||
0, /* no maximum here !! */ |
||||
cache, |
||||
FTC_CACHE(cache)->memory ); |
||||
} |
||||
return error; |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( void ) |
||||
FTC_GCache_Done( FTC_GCache cache ) |
||||
{ |
||||
FTC_Cache_Done( (FTC_Cache)cache ); |
||||
FTC_MruList_Done( &cache->families ); |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_GCache_New( FTC_Manager manager, |
||||
FTC_GCacheClass clazz, |
||||
FTC_GCache *acache ) |
||||
{ |
||||
return FTC_Manager_RegisterCache( manager, (FTC_CacheClass) clazz, |
||||
(FTC_Cache*) acache ); |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_GCache_Lookup( FTC_GCache cache, |
||||
FT_UInt32 hash, |
||||
FT_UInt gindex, |
||||
FTC_GQuery query, |
||||
FTC_Node *anode ) |
||||
{ |
||||
FT_Error error; |
||||
|
||||
query->gindex = gindex; |
||||
|
||||
FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error ); |
||||
if ( !error ) |
||||
error = FTC_Cache_Lookup( FTC_CACHE(cache), hash, query, anode ); |
||||
|
||||
return error; |
||||
} |
||||
|
||||
|
||||
/* END */ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ftcglyph.c */ |
||||
/* */ |
||||
/* FreeType Glyph Image (FT_Glyph) cache (body). */ |
||||
/* */ |
||||
/* 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. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#include <ft2build.h> |
||||
#include FT_CACHE_H |
||||
#include FT_CACHE_INTERNAL_GLYPH_H |
||||
#include FT_ERRORS_H |
||||
#include FT_INTERNAL_OBJECTS_H |
||||
#include FT_INTERNAL_DEBUG_H |
||||
|
||||
#include "ftcerror.h" |
||||
|
||||
|
||||
/* create a new chunk node, setting its cache index and ref count */ |
||||
FT_EXPORT_DEF( void ) |
||||
FTC_GNode_Init( FTC_GNode gnode, |
||||
FT_UInt gindex, |
||||
FTC_Family family ) |
||||
{ |
||||
gnode->family = family; |
||||
gnode->gindex = gindex; |
||||
family->num_nodes++; |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( void ) |
||||
FTC_GNode_UnselectFamily( FTC_GNode gnode, |
||||
FTC_Cache cache ) |
||||
{ |
||||
FTC_Family family = gnode->family; |
||||
|
||||
gnode->family = NULL; |
||||
if ( family && --family->num_nodes <= 0 ) |
||||
{ |
||||
FTC_MruList_Remove( & FTC_GCACHE(cache)->families, (FTC_MruNode)family ); |
||||
} |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( void ) |
||||
FTC_GNode_Done( FTC_GNode gnode, |
||||
FTC_Cache cache ) |
||||
{ |
||||
/* finalize the node */ |
||||
gnode->gindex = 0; |
||||
|
||||
FTC_GNode_UnselectFamily( gnode, cache ); |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Bool ) |
||||
FTC_GNode_Compare( FTC_GNode gnode, |
||||
FTC_GQuery gquery ) |
||||
{ |
||||
return FT_BOOL( gnode->family == gquery->family && |
||||
gnode->gindex == gquery->gindex ); |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/***** *****/ |
||||
/***** CHUNK SETS *****/ |
||||
/***** *****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
FT_EXPORT_DEF( void ) |
||||
FTC_Family_Init( FTC_Family family, |
||||
FTC_Cache cache ) |
||||
{ |
||||
FTC_GCacheClass clazz = FTC_CACHE__GCACHE_CLASS(cache); |
||||
|
||||
family->clazz = clazz->family_class; |
||||
family->num_nodes = 0; |
||||
family->cache = cache; |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_GCache_Init( FTC_GCache cache ) |
||||
{ |
||||
FT_Error error; |
||||
|
||||
error = FTC_Cache_Init( FTC_CACHE(cache) ); |
||||
if ( !error ) |
||||
{ |
||||
FTC_GCacheClass clazz = (FTC_GCacheClass) FTC_CACHE(cache)->org_class; |
||||
|
||||
FTC_MruList_Init( &cache->families, |
||||
clazz->family_class, |
||||
0, /* no maximum here !! */ |
||||
cache, |
||||
FTC_CACHE(cache)->memory ); |
||||
} |
||||
return error; |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( void ) |
||||
FTC_GCache_Done( FTC_GCache cache ) |
||||
{ |
||||
FTC_Cache_Done( (FTC_Cache)cache ); |
||||
FTC_MruList_Done( &cache->families ); |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_GCache_New( FTC_Manager manager, |
||||
FTC_GCacheClass clazz, |
||||
FTC_GCache *acache ) |
||||
{ |
||||
return FTC_Manager_RegisterCache( manager, (FTC_CacheClass) clazz, |
||||
(FTC_Cache*) acache ); |
||||
} |
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FTC_GCache_Lookup( FTC_GCache cache, |
||||
FT_UInt32 hash, |
||||
FT_UInt gindex, |
||||
FTC_GQuery query, |
||||
FTC_Node *anode ) |
||||
{ |
||||
FT_Error error; |
||||
|
||||
query->gindex = gindex; |
||||
|
||||
FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error ); |
||||
if ( !error ) |
||||
error = FTC_Cache_Lookup( FTC_CACHE(cache), hash, query, anode ); |
||||
|
||||
return error; |
||||
} |
||||
|
||||
|
||||
/* END */ |
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue