2018-06-03 09:01:17 +02:00
|
|
|
/****************************************************************************
|
|
|
|
*
|
|
|
|
* ftccache.c
|
|
|
|
*
|
|
|
|
* The FreeType internal cache interface (body).
|
|
|
|
*
|
2020-01-19 17:05:19 +01:00
|
|
|
* Copyright (C) 2000-2020 by
|
2018-06-03 09:01:17 +02:00
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
*/
|
2003-12-24 14:37:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
#include <ft2build.h>
|
* include/freetype/cache/ftccache.h,
include/freetype/cache/ftccmap.h,
include/freetype/cache/ftcglyph.h
include/freetype/cache/ftcimage.h
include/freetype/cache/ftcmanag.h
include/freetype/cache/ftcmru.h
include/freetype/cache/ftcsbits.h:
removing these header files from the public include directory.
* include/freetype/config/ftheader.h:
changing the definition of FT_CACHE_INTERNAL_XXX_H macros to
redirect to FT_CACHE_H instead
* src/cache/ftcbasic.c, src/cache/ftccache.c, src/cache/ftccache.h,
src/cache/ftccback.h, src/cache/ftccmap.c, src/cache/ftcglyph.c,
src/cache/ftcglyph.h, src/cache/ftcimage.c, src/cache/ftcimage.h,
src/cache/ftcmanag.c, src/cache/ftcmanag.h, src/cache/ftcmru.c,
src/cache/ftcmru.h, src/cache/ftcsbits.c, src/cache/ftcsbits.h:
modifications to prevent using the FT_CACHE_INTERNAL_XXX_H macros,
and grab the headers in 'src/cache' instead (see below).
2006-03-20 13:10:24 +01:00
|
|
|
#include "ftcmanag.h"
|
2003-12-24 14:37:58 +01:00
|
|
|
#include FT_INTERNAL_OBJECTS_H
|
|
|
|
#include FT_INTERNAL_DEBUG_H
|
|
|
|
|
Fix callback functions in cache module.
* src/cache/ftccback.h: New file for callback declarations.
* src/cache/ftcbasic.c (ftc_basic_family_compare,
ftc_basic_family_init, ftc_basic_family_get_count,
ftc_basic_family_load_bitmap, ftc_basic_family_load_glyph,
ftc_basic_gnode_compare_faceid): Use FT_CALLBACK_DEF.
(ftc_basic_image_family_class, ftc_basic_image_cache_class,
ftc_basic_sbit_family_class, ftc_basic_sbit_cache_class):
Use FT_CALLBACK_TABLE_DEF and local wrapper functions.
* src/cache/ftccache.c: Include ftccback.h.
(ftc_cache_init, ftc_cache_done): New wrapper functions which use
FT_LOCAL_DEF.
* src/cache/ftccmap.c: Include ftccback.h.
(ftc_cmap_cache_class): Use local wrapper functions.
* src/cache/ftcglyph.c: Include ftccback.h.
(ftc_gnode_compare, ftc_gcache_init, ftc_gcache_done): New wrapper
functions which use FT_LOCAL_DEF.
* src/cache/ftcimage.c: Include ftccback.h.
(ftc_inode_free, ftc_inode_new, ftc_inode_weight): New wrapper
functions which use FT_LOCAL_DEF.
* src/cache/ftcmanag.c (ftc_size_list_class, ftc_face_list_class):
Use FT_CALLBACK_TABLE_DEF.
* src/cache;/ftcsbits.c: Include ftccback.h.
(ftc_snode_free, ftc_snode_new, ftc_snode_weight,
ftc_snode_compare): New wrapper functions which use FT_LOCAL_DEF.
* src/cache/rules.mk (CACHE_DRV_H): Add ftccback.h.
2004-02-17 19:41:58 +01:00
|
|
|
#include "ftccback.h"
|
2003-12-24 14:37:58 +01:00
|
|
|
#include "ftcerror.h"
|
|
|
|
|
2009-10-06 11:09:29 +02:00
|
|
|
#undef FT_COMPONENT
|
2018-08-15 18:13:17 +02:00
|
|
|
#define FT_COMPONENT cache
|
2009-10-06 11:09:29 +02:00
|
|
|
|
2003-12-24 14:37:58 +01:00
|
|
|
|
|
|
|
#define FTC_HASH_MAX_LOAD 2
|
|
|
|
#define FTC_HASH_MIN_LOAD 1
|
|
|
|
#define FTC_HASH_SUB_LOAD ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD )
|
|
|
|
|
2011-01-13 10:33:04 +01:00
|
|
|
/* this one _must_ be a power of 2! */
|
2003-12-24 14:37:58 +01:00
|
|
|
#define FTC_HASH_INITIAL_SIZE 8
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/***** *****/
|
|
|
|
/***** CACHE NODE DEFINITIONS *****/
|
|
|
|
/***** *****/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
/* add a new node to the head of the manager's circular MRU list */
|
|
|
|
static void
|
|
|
|
ftc_node_mru_link( FTC_Node node,
|
|
|
|
FTC_Manager manager )
|
|
|
|
{
|
2007-05-16 17:19:42 +02:00
|
|
|
void *nl = &manager->nodes_list;
|
|
|
|
|
|
|
|
|
|
|
|
FTC_MruNode_Prepend( (FTC_MruNode*)nl,
|
2003-12-26 08:26:08 +01:00
|
|
|
(FTC_MruNode)node );
|
2003-12-24 14:37:58 +01:00
|
|
|
manager->num_nodes++;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* remove a node from the manager's MRU list */
|
|
|
|
static void
|
|
|
|
ftc_node_mru_unlink( FTC_Node node,
|
|
|
|
FTC_Manager manager )
|
|
|
|
{
|
2007-05-16 17:19:42 +02:00
|
|
|
void *nl = &manager->nodes_list;
|
|
|
|
|
|
|
|
|
|
|
|
FTC_MruNode_Remove( (FTC_MruNode*)nl,
|
2003-12-26 08:26:08 +01:00
|
|
|
(FTC_MruNode)node );
|
2003-12-24 14:37:58 +01:00
|
|
|
manager->num_nodes--;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
* src/cache/ftccache.c, (ftc_node_mru_up, FTC_Cache_Lookup)
[!FTC_INLINE]: Compile conditionally.
* src/cache/ftccache.h: Updated.
* src/cache/ftcglyph.c (FTC_GNode_Init, FTC_GNode_UnselectFamily,
FTC_GNode_Done, FTC_GNode_Compare, FTC_Family_Init, FTC_GCache_New):
s/FT_EXPORT/FT_LOCAL/.
(FTC_GCache_Init, FTC_GCache_Done): Commented out.
(FTC_GCache_Lookup) [!FTC_INLINE]: Compile conditionally.
s/FT_EXPORT/FT_LOCAL/.
* src/cache/ftcglyph.h: Updated.
* src/cache/ftcimage.c (FTC_INode_Free, FTC_INode_New):
s/FT_EXPORT/FT_LOCAL/.
(FTC_INode_Weight): Commented out.
* src/cache/ftcimage.h: Updated.
* src/cache/ftmanag.c (FTC_Manager_Compress,
FTC_Manager_RegisterCache, FTC_Manager_FlushN):
s/FT_EXPORT/FT_LOCAL/.
* src/cache/ftmanag.h: Updated.
* src/cache/ftcsbits.c (FTC_SNode_Free, FTC_SNode_New,
FTC_SNode_Compare): s/FT_EXPORT/FT_LOCAL/.
(FTC_SNode_Weight): Commented out.
* src/cache/ftcsbits.h: Updated.
2006-03-22 16:30:41 +01:00
|
|
|
#ifndef FTC_INLINE
|
|
|
|
|
2003-12-24 14:37:58 +01:00
|
|
|
/* move a node to the head of the manager's MRU list */
|
|
|
|
static void
|
|
|
|
ftc_node_mru_up( FTC_Node node,
|
|
|
|
FTC_Manager manager )
|
|
|
|
{
|
2003-12-26 08:26:08 +01:00
|
|
|
FTC_MruNode_Up( (FTC_MruNode*)&manager->nodes_list,
|
|
|
|
(FTC_MruNode)node );
|
2003-12-24 14:37:58 +01:00
|
|
|
}
|
|
|
|
|
2011-01-09 13:09:58 +01:00
|
|
|
|
|
|
|
/* get a top bucket for specified hash from cache,
|
2016-01-12 21:40:53 +01:00
|
|
|
* body for FTC_NODE_TOP_FOR_HASH( cache, hash )
|
2011-01-09 13:09:58 +01:00
|
|
|
*/
|
|
|
|
FT_LOCAL_DEF( FTC_Node* )
|
2015-02-23 08:20:27 +01:00
|
|
|
ftc_get_top_node_for_hash( FTC_Cache cache,
|
|
|
|
FT_Offset hash )
|
2011-01-09 13:09:58 +01:00
|
|
|
{
|
|
|
|
FTC_Node* pnode;
|
2015-02-23 08:20:27 +01:00
|
|
|
FT_Offset idx;
|
2011-01-09 13:09:58 +01:00
|
|
|
|
|
|
|
|
2015-02-23 08:20:27 +01:00
|
|
|
idx = hash & cache->mask;
|
2011-01-09 13:09:58 +01:00
|
|
|
if ( idx < cache->p )
|
2015-02-23 08:20:27 +01:00
|
|
|
idx = hash & ( 2 * cache->mask + 1 );
|
2011-01-09 13:09:58 +01:00
|
|
|
pnode = cache->buckets + idx;
|
|
|
|
return pnode;
|
|
|
|
}
|
|
|
|
|
* src/cache/ftccache.c, (ftc_node_mru_up, FTC_Cache_Lookup)
[!FTC_INLINE]: Compile conditionally.
* src/cache/ftccache.h: Updated.
* src/cache/ftcglyph.c (FTC_GNode_Init, FTC_GNode_UnselectFamily,
FTC_GNode_Done, FTC_GNode_Compare, FTC_Family_Init, FTC_GCache_New):
s/FT_EXPORT/FT_LOCAL/.
(FTC_GCache_Init, FTC_GCache_Done): Commented out.
(FTC_GCache_Lookup) [!FTC_INLINE]: Compile conditionally.
s/FT_EXPORT/FT_LOCAL/.
* src/cache/ftcglyph.h: Updated.
* src/cache/ftcimage.c (FTC_INode_Free, FTC_INode_New):
s/FT_EXPORT/FT_LOCAL/.
(FTC_INode_Weight): Commented out.
* src/cache/ftcimage.h: Updated.
* src/cache/ftmanag.c (FTC_Manager_Compress,
FTC_Manager_RegisterCache, FTC_Manager_FlushN):
s/FT_EXPORT/FT_LOCAL/.
* src/cache/ftmanag.h: Updated.
* src/cache/ftcsbits.c (FTC_SNode_Free, FTC_SNode_New,
FTC_SNode_Compare): s/FT_EXPORT/FT_LOCAL/.
(FTC_SNode_Weight): Commented out.
* src/cache/ftcsbits.h: Updated.
2006-03-22 16:30:41 +01:00
|
|
|
#endif /* !FTC_INLINE */
|
|
|
|
|
2003-12-24 14:37:58 +01:00
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
/* Note that this function cannot fail. If we cannot re-size the
|
|
|
|
* buckets array appropriately, we simply degrade the hash table's
|
|
|
|
* performance!
|
|
|
|
*/
|
2003-12-24 14:37:58 +01:00
|
|
|
static void
|
|
|
|
ftc_cache_resize( FTC_Cache cache )
|
|
|
|
{
|
|
|
|
for (;;)
|
|
|
|
{
|
2003-12-26 08:26:08 +01:00
|
|
|
FTC_Node node, *pnode;
|
2011-01-13 10:33:04 +01:00
|
|
|
FT_UFast p = cache->p;
|
|
|
|
FT_UFast mask = cache->mask;
|
|
|
|
FT_UFast count = mask + p + 1; /* number of buckets */
|
2003-12-24 14:37:58 +01:00
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
|
|
|
|
/* do we need to shrink the buckets array? */
|
2003-12-24 14:37:58 +01:00
|
|
|
if ( cache->slack < 0 )
|
|
|
|
{
|
2003-12-26 08:26:08 +01:00
|
|
|
FTC_Node new_list = NULL;
|
|
|
|
|
2003-12-24 14:37:58 +01:00
|
|
|
|
|
|
|
/* try to expand the buckets array _before_ splitting
|
|
|
|
* the bucket lists
|
|
|
|
*/
|
2003-12-26 08:26:08 +01:00
|
|
|
if ( p >= mask )
|
|
|
|
{
|
|
|
|
FT_Memory memory = cache->memory;
|
2006-01-27 13:11:22 +01:00
|
|
|
FT_Error error;
|
2003-12-26 08:26:08 +01:00
|
|
|
|
2003-12-24 14:37:58 +01:00
|
|
|
|
|
|
|
/* if we can't expand the array, leave immediately */
|
2011-01-13 10:33:04 +01:00
|
|
|
if ( FT_RENEW_ARRAY( cache->buckets,
|
|
|
|
( mask + 1 ) * 2, ( mask + 1 ) * 4 ) )
|
2003-12-26 08:26:08 +01:00
|
|
|
break;
|
|
|
|
}
|
2003-12-24 14:37:58 +01:00
|
|
|
|
|
|
|
/* split a single bucket */
|
2003-12-26 08:26:08 +01:00
|
|
|
pnode = cache->buckets + p;
|
2003-12-24 14:37:58 +01:00
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
node = *pnode;
|
2016-12-26 17:08:17 +01:00
|
|
|
if ( !node )
|
2003-12-26 08:26:08 +01:00
|
|
|
break;
|
2003-12-24 14:37:58 +01:00
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
if ( node->hash & ( mask + 1 ) )
|
|
|
|
{
|
|
|
|
*pnode = node->link;
|
|
|
|
node->link = new_list;
|
|
|
|
new_list = node;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pnode = &node->link;
|
|
|
|
}
|
2003-12-24 14:37:58 +01:00
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
cache->buckets[p + mask + 1] = new_list;
|
2003-12-24 14:37:58 +01:00
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
cache->slack += FTC_HASH_MAX_LOAD;
|
2003-12-24 14:37:58 +01:00
|
|
|
|
|
|
|
if ( p >= mask )
|
|
|
|
{
|
|
|
|
cache->mask = 2 * mask + 1;
|
|
|
|
cache->p = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
cache->p = p + 1;
|
|
|
|
}
|
2003-12-26 08:26:08 +01:00
|
|
|
|
|
|
|
/* do we need to expand the buckets array? */
|
2003-12-24 14:37:58 +01:00
|
|
|
else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD )
|
|
|
|
{
|
2009-07-31 17:30:19 +02:00
|
|
|
FT_UFast old_index = p + mask;
|
2003-12-24 14:37:58 +01:00
|
|
|
FTC_Node* pold;
|
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
|
2003-12-24 14:37:58 +01:00
|
|
|
if ( old_index + 1 <= FTC_HASH_INITIAL_SIZE )
|
|
|
|
break;
|
|
|
|
|
|
|
|
if ( p == 0 )
|
|
|
|
{
|
|
|
|
FT_Memory memory = cache->memory;
|
2006-01-27 13:11:22 +01:00
|
|
|
FT_Error error;
|
2003-12-24 14:37:58 +01:00
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
|
|
|
|
/* if we can't shrink the array, leave immediately */
|
2006-01-27 13:11:22 +01:00
|
|
|
if ( FT_RENEW_ARRAY( cache->buckets,
|
|
|
|
( mask + 1 ) * 2, mask + 1 ) )
|
2003-12-24 14:37:58 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
cache->mask >>= 1;
|
|
|
|
p = cache->mask;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
p--;
|
|
|
|
|
|
|
|
pnode = cache->buckets + p;
|
|
|
|
while ( *pnode )
|
|
|
|
pnode = &(*pnode)->link;
|
|
|
|
|
|
|
|
pold = cache->buckets + old_index;
|
|
|
|
*pnode = *pold;
|
|
|
|
*pold = NULL;
|
|
|
|
|
|
|
|
cache->slack -= FTC_HASH_MAX_LOAD;
|
|
|
|
cache->p = p;
|
|
|
|
}
|
2011-01-13 10:33:04 +01:00
|
|
|
|
|
|
|
/* otherwise, the hash table is balanced */
|
|
|
|
else
|
2003-12-24 14:37:58 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* remove a node from its cache's hash table */
|
|
|
|
static void
|
|
|
|
ftc_node_hash_unlink( FTC_Node node0,
|
|
|
|
FTC_Cache cache )
|
|
|
|
{
|
2016-01-12 21:40:53 +01:00
|
|
|
FTC_Node *pnode = FTC_NODE_TOP_FOR_HASH( cache, node0->hash );
|
2003-12-24 14:37:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
FTC_Node node = *pnode;
|
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
|
2016-12-26 17:08:17 +01:00
|
|
|
if ( !node )
|
2003-12-24 14:37:58 +01:00
|
|
|
{
|
2009-06-26 06:15:41 +02:00
|
|
|
FT_TRACE0(( "ftc_node_hash_unlink: unknown node\n" ));
|
2003-12-24 14:37:58 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( node == node0 )
|
|
|
|
break;
|
|
|
|
|
|
|
|
pnode = &(*pnode)->link;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pnode = node0->link;
|
|
|
|
node0->link = NULL;
|
|
|
|
|
|
|
|
cache->slack++;
|
|
|
|
ftc_cache_resize( cache );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
/* add a node to the `top' of its cache's hash table */
|
2003-12-24 14:37:58 +01:00
|
|
|
static void
|
|
|
|
ftc_node_hash_link( FTC_Node node,
|
|
|
|
FTC_Cache cache )
|
|
|
|
{
|
2016-01-12 21:40:53 +01:00
|
|
|
FTC_Node *pnode = FTC_NODE_TOP_FOR_HASH( cache, node->hash );
|
2003-12-24 14:37:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
node->link = *pnode;
|
|
|
|
*pnode = node;
|
|
|
|
|
|
|
|
cache->slack--;
|
|
|
|
ftc_cache_resize( cache );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-12 18:07:11 +01:00
|
|
|
/* remove a node from the cache manager */
|
2006-02-27 20:49:34 +01:00
|
|
|
FT_LOCAL_DEF( void )
|
2003-12-24 14:37:58 +01:00
|
|
|
ftc_node_destroy( FTC_Node node,
|
|
|
|
FTC_Manager manager )
|
|
|
|
{
|
|
|
|
FTC_Cache cache;
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef FT_DEBUG_ERROR
|
|
|
|
/* find node's cache */
|
|
|
|
if ( node->cache_index >= manager->num_caches )
|
|
|
|
{
|
2009-06-26 06:15:41 +02:00
|
|
|
FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" ));
|
2003-12-24 14:37:58 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
cache = manager->caches[node->cache_index];
|
2003-12-24 14:37:58 +01:00
|
|
|
|
|
|
|
#ifdef FT_DEBUG_ERROR
|
2016-12-26 17:08:17 +01:00
|
|
|
if ( !cache )
|
2003-12-24 14:37:58 +01:00
|
|
|
{
|
2009-06-26 06:15:41 +02:00
|
|
|
FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" ));
|
2003-12-24 14:37:58 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
manager->cur_weight -= cache->clazz.node_weight( node, cache );
|
|
|
|
|
|
|
|
/* remove node from mru list */
|
|
|
|
ftc_node_mru_unlink( node, manager );
|
|
|
|
|
|
|
|
/* remove node from cache's hash table */
|
|
|
|
ftc_node_hash_unlink( node, cache );
|
|
|
|
|
|
|
|
/* now finalize it */
|
|
|
|
cache->clazz.node_free( node, cache );
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* check, just in case of general corruption :-) */
|
|
|
|
if ( manager->num_nodes == 0 )
|
2009-06-26 06:15:41 +02:00
|
|
|
FT_TRACE0(( "ftc_node_destroy: invalid cache node count (%d)\n",
|
2003-12-24 14:37:58 +01:00
|
|
|
manager->num_nodes ));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/***** *****/
|
|
|
|
/***** ABSTRACT CACHE CLASS *****/
|
|
|
|
/***** *****/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
* include/freetype/cache/ftccache.h,
include/freetype/cache/ftccmap.h,
include/freetype/cache/ftcglyph.h
include/freetype/cache/ftcimage.h
include/freetype/cache/ftcmanag.h
include/freetype/cache/ftcmru.h
include/freetype/cache/ftcsbits.h:
removing these header files from the public include directory.
* include/freetype/config/ftheader.h:
changing the definition of FT_CACHE_INTERNAL_XXX_H macros to
redirect to FT_CACHE_H instead
* src/cache/ftcbasic.c, src/cache/ftccache.c, src/cache/ftccache.h,
src/cache/ftccback.h, src/cache/ftccmap.c, src/cache/ftcglyph.c,
src/cache/ftcglyph.h, src/cache/ftcimage.c, src/cache/ftcimage.h,
src/cache/ftcmanag.c, src/cache/ftcmanag.h, src/cache/ftcmru.c,
src/cache/ftcmru.h, src/cache/ftcsbits.c, src/cache/ftcsbits.h:
modifications to prevent using the FT_CACHE_INTERNAL_XXX_H macros,
and grab the headers in 'src/cache' instead (see below).
2006-03-20 13:10:24 +01:00
|
|
|
FT_LOCAL_DEF( FT_Error )
|
2003-12-26 08:26:08 +01:00
|
|
|
FTC_Cache_Init( FTC_Cache cache )
|
2004-06-09 23:07:49 +02:00
|
|
|
{
|
|
|
|
return ftc_cache_init( cache );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FT_LOCAL_DEF( FT_Error )
|
|
|
|
ftc_cache_init( FTC_Cache cache )
|
2003-12-24 14:37:58 +01:00
|
|
|
{
|
|
|
|
FT_Memory memory = cache->memory;
|
2006-01-27 13:11:22 +01:00
|
|
|
FT_Error error;
|
2003-12-24 14:37:58 +01:00
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
|
|
|
|
cache->p = 0;
|
|
|
|
cache->mask = FTC_HASH_INITIAL_SIZE - 1;
|
|
|
|
cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD;
|
2003-12-24 14:37:58 +01:00
|
|
|
|
2006-01-27 13:11:22 +01:00
|
|
|
(void)FT_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 );
|
|
|
|
return error;
|
2003-12-24 14:37:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-12 18:07:11 +01:00
|
|
|
static void
|
2003-12-24 14:37:58 +01:00
|
|
|
FTC_Cache_Clear( FTC_Cache cache )
|
|
|
|
{
|
2010-08-17 07:40:55 +02:00
|
|
|
if ( cache && cache->buckets )
|
2003-12-24 14:37:58 +01:00
|
|
|
{
|
|
|
|
FTC_Manager manager = cache->manager;
|
|
|
|
FT_UFast i;
|
2009-07-31 17:30:19 +02:00
|
|
|
FT_UFast count;
|
2003-12-24 14:37:58 +01:00
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
|
2003-12-24 14:37:58 +01:00
|
|
|
count = cache->p + cache->mask + 1;
|
|
|
|
|
|
|
|
for ( i = 0; i < count; i++ )
|
|
|
|
{
|
|
|
|
FTC_Node *pnode = cache->buckets + i, next, node = *pnode;
|
|
|
|
|
|
|
|
|
|
|
|
while ( node )
|
|
|
|
{
|
|
|
|
next = node->link;
|
|
|
|
node->link = NULL;
|
|
|
|
|
|
|
|
/* remove node from mru list */
|
|
|
|
ftc_node_mru_unlink( node, manager );
|
|
|
|
|
|
|
|
/* now finalize it */
|
|
|
|
manager->cur_weight -= cache->clazz.node_weight( node, cache );
|
|
|
|
|
|
|
|
cache->clazz.node_free( node, cache );
|
|
|
|
node = next;
|
|
|
|
}
|
|
|
|
cache->buckets[i] = NULL;
|
|
|
|
}
|
|
|
|
ftc_cache_resize( cache );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-09 23:07:49 +02:00
|
|
|
FT_LOCAL_DEF( void )
|
|
|
|
ftc_cache_done( FTC_Cache cache )
|
2003-12-24 14:37:58 +01:00
|
|
|
{
|
|
|
|
if ( cache->memory )
|
|
|
|
{
|
|
|
|
FT_Memory memory = cache->memory;
|
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
|
2003-12-24 14:37:58 +01:00
|
|
|
FTC_Cache_Clear( cache );
|
|
|
|
|
|
|
|
FT_FREE( cache->buckets );
|
|
|
|
cache->mask = 0;
|
|
|
|
cache->p = 0;
|
|
|
|
cache->slack = 0;
|
|
|
|
|
|
|
|
cache->memory = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
* include/freetype/cache/ftccache.h,
include/freetype/cache/ftccmap.h,
include/freetype/cache/ftcglyph.h
include/freetype/cache/ftcimage.h
include/freetype/cache/ftcmanag.h
include/freetype/cache/ftcmru.h
include/freetype/cache/ftcsbits.h:
removing these header files from the public include directory.
* include/freetype/config/ftheader.h:
changing the definition of FT_CACHE_INTERNAL_XXX_H macros to
redirect to FT_CACHE_H instead
* src/cache/ftcbasic.c, src/cache/ftccache.c, src/cache/ftccache.h,
src/cache/ftccback.h, src/cache/ftccmap.c, src/cache/ftcglyph.c,
src/cache/ftcglyph.h, src/cache/ftcimage.c, src/cache/ftcimage.h,
src/cache/ftcmanag.c, src/cache/ftcmanag.h, src/cache/ftcmru.c,
src/cache/ftcmru.h, src/cache/ftcsbits.c, src/cache/ftcsbits.h:
modifications to prevent using the FT_CACHE_INTERNAL_XXX_H macros,
and grab the headers in 'src/cache' instead (see below).
2006-03-20 13:10:24 +01:00
|
|
|
FT_LOCAL_DEF( void )
|
2004-06-09 23:07:49 +02:00
|
|
|
FTC_Cache_Done( FTC_Cache cache )
|
Fix callback functions in cache module.
* src/cache/ftccback.h: New file for callback declarations.
* src/cache/ftcbasic.c (ftc_basic_family_compare,
ftc_basic_family_init, ftc_basic_family_get_count,
ftc_basic_family_load_bitmap, ftc_basic_family_load_glyph,
ftc_basic_gnode_compare_faceid): Use FT_CALLBACK_DEF.
(ftc_basic_image_family_class, ftc_basic_image_cache_class,
ftc_basic_sbit_family_class, ftc_basic_sbit_cache_class):
Use FT_CALLBACK_TABLE_DEF and local wrapper functions.
* src/cache/ftccache.c: Include ftccback.h.
(ftc_cache_init, ftc_cache_done): New wrapper functions which use
FT_LOCAL_DEF.
* src/cache/ftccmap.c: Include ftccback.h.
(ftc_cmap_cache_class): Use local wrapper functions.
* src/cache/ftcglyph.c: Include ftccback.h.
(ftc_gnode_compare, ftc_gcache_init, ftc_gcache_done): New wrapper
functions which use FT_LOCAL_DEF.
* src/cache/ftcimage.c: Include ftccback.h.
(ftc_inode_free, ftc_inode_new, ftc_inode_weight): New wrapper
functions which use FT_LOCAL_DEF.
* src/cache/ftcmanag.c (ftc_size_list_class, ftc_face_list_class):
Use FT_CALLBACK_TABLE_DEF.
* src/cache;/ftcsbits.c: Include ftccback.h.
(ftc_snode_free, ftc_snode_new, ftc_snode_weight,
ftc_snode_compare): New wrapper functions which use FT_LOCAL_DEF.
* src/cache/rules.mk (CACHE_DRV_H): Add ftccback.h.
2004-02-17 19:41:58 +01:00
|
|
|
{
|
2004-06-09 23:07:49 +02:00
|
|
|
ftc_cache_done( cache );
|
Fix callback functions in cache module.
* src/cache/ftccback.h: New file for callback declarations.
* src/cache/ftcbasic.c (ftc_basic_family_compare,
ftc_basic_family_init, ftc_basic_family_get_count,
ftc_basic_family_load_bitmap, ftc_basic_family_load_glyph,
ftc_basic_gnode_compare_faceid): Use FT_CALLBACK_DEF.
(ftc_basic_image_family_class, ftc_basic_image_cache_class,
ftc_basic_sbit_family_class, ftc_basic_sbit_cache_class):
Use FT_CALLBACK_TABLE_DEF and local wrapper functions.
* src/cache/ftccache.c: Include ftccback.h.
(ftc_cache_init, ftc_cache_done): New wrapper functions which use
FT_LOCAL_DEF.
* src/cache/ftccmap.c: Include ftccback.h.
(ftc_cmap_cache_class): Use local wrapper functions.
* src/cache/ftcglyph.c: Include ftccback.h.
(ftc_gnode_compare, ftc_gcache_init, ftc_gcache_done): New wrapper
functions which use FT_LOCAL_DEF.
* src/cache/ftcimage.c: Include ftccback.h.
(ftc_inode_free, ftc_inode_new, ftc_inode_weight): New wrapper
functions which use FT_LOCAL_DEF.
* src/cache/ftcmanag.c (ftc_size_list_class, ftc_face_list_class):
Use FT_CALLBACK_TABLE_DEF.
* src/cache;/ftcsbits.c: Include ftccback.h.
(ftc_snode_free, ftc_snode_new, ftc_snode_weight,
ftc_snode_compare): New wrapper functions which use FT_LOCAL_DEF.
* src/cache/rules.mk (CACHE_DRV_H): Add ftccback.h.
2004-02-17 19:41:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-24 14:37:58 +01:00
|
|
|
static void
|
2003-12-26 08:26:08 +01:00
|
|
|
ftc_cache_add( FTC_Cache cache,
|
2015-02-23 08:20:27 +01:00
|
|
|
FT_Offset hash,
|
2003-12-26 08:26:08 +01:00
|
|
|
FTC_Node node )
|
2003-12-24 14:37:58 +01:00
|
|
|
{
|
2011-01-13 10:33:04 +01:00
|
|
|
node->hash = hash;
|
|
|
|
node->cache_index = (FT_UInt16)cache->index;
|
2003-12-24 14:37:58 +01:00
|
|
|
node->ref_count = 0;
|
|
|
|
|
|
|
|
ftc_node_hash_link( node, cache );
|
|
|
|
ftc_node_mru_link( node, cache->manager );
|
|
|
|
|
|
|
|
{
|
|
|
|
FTC_Manager manager = cache->manager;
|
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
|
2003-12-24 14:37:58 +01:00
|
|
|
manager->cur_weight += cache->clazz.node_weight( node, cache );
|
|
|
|
|
|
|
|
if ( manager->cur_weight >= manager->max_weight )
|
|
|
|
{
|
|
|
|
node->ref_count++;
|
|
|
|
FTC_Manager_Compress( manager );
|
|
|
|
node->ref_count--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
* include/freetype/cache/ftccache.h,
include/freetype/cache/ftccmap.h,
include/freetype/cache/ftcglyph.h
include/freetype/cache/ftcimage.h
include/freetype/cache/ftcmanag.h
include/freetype/cache/ftcmru.h
include/freetype/cache/ftcsbits.h:
removing these header files from the public include directory.
* include/freetype/config/ftheader.h:
changing the definition of FT_CACHE_INTERNAL_XXX_H macros to
redirect to FT_CACHE_H instead
* src/cache/ftcbasic.c, src/cache/ftccache.c, src/cache/ftccache.h,
src/cache/ftccback.h, src/cache/ftccmap.c, src/cache/ftcglyph.c,
src/cache/ftcglyph.h, src/cache/ftcimage.c, src/cache/ftcimage.h,
src/cache/ftcmanag.c, src/cache/ftcmanag.h, src/cache/ftcmru.c,
src/cache/ftcmru.h, src/cache/ftcsbits.c, src/cache/ftcsbits.h:
modifications to prevent using the FT_CACHE_INTERNAL_XXX_H macros,
and grab the headers in 'src/cache' instead (see below).
2006-03-20 13:10:24 +01:00
|
|
|
FT_LOCAL_DEF( FT_Error )
|
2003-12-24 14:37:58 +01:00
|
|
|
FTC_Cache_NewNode( FTC_Cache cache,
|
2015-02-23 08:20:27 +01:00
|
|
|
FT_Offset hash,
|
2003-12-24 14:37:58 +01:00
|
|
|
FT_Pointer query,
|
|
|
|
FTC_Node *anode )
|
|
|
|
{
|
|
|
|
FT_Error error;
|
|
|
|
FTC_Node node;
|
|
|
|
|
* builds/amiga/makefile.os4 (WARNINGS), builds/compiler/gcc-dev.mk
(CFLAGS), builds/compiler/gcc.mk (CFLAGS): Remove
-fno-strict-aliasing.
Say you have `(Foo*)x' and want to assign, pass, or return it as
`(Bar*)'. If you simply say `x' or `(Bar*)x', then the C compiler
would warn you that type casting incompatible pointer types breaks
strict-aliasing. The solution is to cast to `(void*)' instead which
is the generic pointer type, so the compiler knows that it should
make no strict-aliasing assumption on `x'. But the problem with
`(void*)x' is that seems like in C++, unlike C, `void*' is not a
generic pointer type and assigning `void*' to `Bar*' without a cast
causes an error. The solution is to cast to `Bar*' too, with
`(Bar*)(void*)x' as the result -- this is what the patch does.
* include/freetype/cache/ftccache.h (FTC_CACHE_LOOKUP_CMP),
include/freetype/cache/ftcmru.h (FTC_MRULIST_LOOKUP_CMP): Remove
cast on lvalue, use a temporary pointer instead.
Cast temporarily to (void*) to not break strict aliasing.
* include/freetype/internal/ftmemory.h (FT_MEM_ALLOC,
FT_MEM_REALLOC, FT_MEM_QALLOC, FT_MEM_QREALLOC, FT_MEM_FREE),
src/base/ftglyph.c (FT_Glyph_To_Bitmap): Cast temporarily to (void*)
to not break strict aliasing.
* src/base/ftinit.c (FT_USE_MODULE): Fix wrong type information.
* builds/unix/configure.ac (XX_CFLAGS): Remove -fno-strict-aliasing.
* src/sfnt/rules.mk (SFNT_DRV_SRC): Don't include ttsbit0.c --
it is currently loaded from ttsbit.c.
Other formatting.
2005-05-23 23:33:02 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We use the FTC_CACHE_TRYLOOP macros to support out-of-memory
|
|
|
|
* errors (OOM) correctly, i.e., by flushing the cache progressively
|
|
|
|
* in order to make more room.
|
|
|
|
*/
|
|
|
|
|
|
|
|
FTC_CACHE_TRYLOOP( cache )
|
2005-05-23 15:04:53 +02:00
|
|
|
{
|
|
|
|
error = cache->clazz.node_new( &node, query, cache );
|
|
|
|
}
|
[cache] Notice if a cache query induced the node list change.
Some node comparators (comparing the cache node content and
the properties specified by the query) can flush the cache
node to prevent the cache inflation. The change may
invalidate the pointers to the node obtained before the node
comparison, so the change should be noticed to the caller.
The problem caused by the cache node changing is reported by
Harsha, see Savannah bug #31923.
* src/cache/ftccache.h (FTC_Node_CompareFunc): Add new
argument `FT_Bool* list_changed' to indicate the change of
the cached nodes to the caller.
(FTC_CACHE_LOOKUP_CMP): Watch the change of the cached nodes
by `_list_changed'.
(FTC_CACHE_TRYLOOP_END): Take new macro argument `_list_changed'
and update it when FTC_Manager_FlushN() flushes any nodes.
* src/cache/ftccback.h (ftc_snode_compare): Updated to fit
with new FTC_Node_CompareFunc type. (ftc_gnode_compare): Ditto.
* src/cache/ftcbasic.c: Include FT_INTERNAL_OBJECTS_H to
use TRUE/FALSE macros. (ftc_basic_gnode_compare_faceid):
New argument `FT_Bool* list_changed' to indicate the change
of the cache nodes, anyway, it is always FALSE.
* src/cache/ftccmap.c: Include FT_INTERNAL_OBJECTS_H to
use TRUE/FALSE macros. (ftc_cmap_node_compare):
New argument `FT_Bool* list_changed' to indicate the change
of the cache nodes, anyway, it is always FALSE.
(ftc_cmap_node_remove_faceid): Ditto.
* src/cache/ftccache.c (FTC_Cache_NewNode): Pass a NULL
pointer to FTC_CACHE_TRYLOOP_END(), because the result is
not needed. (FTC_Cache_Lookup): Watch the change of the cache
nodes by `list_changed'. (FTC_Cache_RemoveFaceID): Ditto.
* src/cache/ftcglyph.c: Include FT_INTERNAL_OBJECTS_H to
use TRUE/FALSE macros. (ftc_gnode_compare): New argument
`FT_Bool* list_changed' to indicate the change of the cache
nodes, anyway, it is always FALSE. (FTC_GNode_Compare):
New argument `FT_Bool* list_changed' to be passed to
ftc_gnode_compare().
* src/cache/ftcglyph.h (FTC_GNode_Compare): Ditto.
* src/cache/ftcsbits.c (ftc_snode_compare): New argument
`FT_Bool* list_changed' to indicate the change of the cache
nodes, anyway. It is updated by FTC_CACHE_TRYLOOP().
(FTC_SNode_Compare): New argument `FT_Bool* list_changed'
to be passed to ftc_snode_compare().
* src/cache/ftcsbits.h (FTC_SNode_Compare): Ditto.
2011-01-09 14:49:07 +01:00
|
|
|
FTC_CACHE_TRYLOOP_END( NULL );
|
2003-12-24 14:37:58 +01:00
|
|
|
|
2005-05-23 15:04:53 +02:00
|
|
|
if ( error )
|
|
|
|
node = NULL;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* don't assume that the cache has the same number of buckets, since
|
|
|
|
* our allocation request might have triggered global cache flushing
|
|
|
|
*/
|
|
|
|
ftc_cache_add( cache, hash, node );
|
|
|
|
}
|
2003-12-24 14:37:58 +01:00
|
|
|
|
|
|
|
*anode = node;
|
|
|
|
return error;
|
2003-12-24 19:42:04 +01:00
|
|
|
}
|
2003-12-24 14:37:58 +01:00
|
|
|
|
|
|
|
|
* src/cache/ftccache.c, (ftc_node_mru_up, FTC_Cache_Lookup)
[!FTC_INLINE]: Compile conditionally.
* src/cache/ftccache.h: Updated.
* src/cache/ftcglyph.c (FTC_GNode_Init, FTC_GNode_UnselectFamily,
FTC_GNode_Done, FTC_GNode_Compare, FTC_Family_Init, FTC_GCache_New):
s/FT_EXPORT/FT_LOCAL/.
(FTC_GCache_Init, FTC_GCache_Done): Commented out.
(FTC_GCache_Lookup) [!FTC_INLINE]: Compile conditionally.
s/FT_EXPORT/FT_LOCAL/.
* src/cache/ftcglyph.h: Updated.
* src/cache/ftcimage.c (FTC_INode_Free, FTC_INode_New):
s/FT_EXPORT/FT_LOCAL/.
(FTC_INode_Weight): Commented out.
* src/cache/ftcimage.h: Updated.
* src/cache/ftmanag.c (FTC_Manager_Compress,
FTC_Manager_RegisterCache, FTC_Manager_FlushN):
s/FT_EXPORT/FT_LOCAL/.
* src/cache/ftmanag.h: Updated.
* src/cache/ftcsbits.c (FTC_SNode_Free, FTC_SNode_New,
FTC_SNode_Compare): s/FT_EXPORT/FT_LOCAL/.
(FTC_SNode_Weight): Commented out.
* src/cache/ftcsbits.h: Updated.
2006-03-22 16:30:41 +01:00
|
|
|
#ifndef FTC_INLINE
|
|
|
|
|
* include/freetype/cache/ftccache.h,
include/freetype/cache/ftccmap.h,
include/freetype/cache/ftcglyph.h
include/freetype/cache/ftcimage.h
include/freetype/cache/ftcmanag.h
include/freetype/cache/ftcmru.h
include/freetype/cache/ftcsbits.h:
removing these header files from the public include directory.
* include/freetype/config/ftheader.h:
changing the definition of FT_CACHE_INTERNAL_XXX_H macros to
redirect to FT_CACHE_H instead
* src/cache/ftcbasic.c, src/cache/ftccache.c, src/cache/ftccache.h,
src/cache/ftccback.h, src/cache/ftccmap.c, src/cache/ftcglyph.c,
src/cache/ftcglyph.h, src/cache/ftcimage.c, src/cache/ftcimage.h,
src/cache/ftcmanag.c, src/cache/ftcmanag.h, src/cache/ftcmru.c,
src/cache/ftcmru.h, src/cache/ftcsbits.c, src/cache/ftcsbits.h:
modifications to prevent using the FT_CACHE_INTERNAL_XXX_H macros,
and grab the headers in 'src/cache' instead (see below).
2006-03-20 13:10:24 +01:00
|
|
|
FT_LOCAL_DEF( FT_Error )
|
2003-12-24 14:37:58 +01:00
|
|
|
FTC_Cache_Lookup( FTC_Cache cache,
|
2015-02-23 08:20:27 +01:00
|
|
|
FT_Offset hash,
|
2003-12-24 14:37:58 +01:00
|
|
|
FT_Pointer query,
|
|
|
|
FTC_Node *anode )
|
|
|
|
{
|
|
|
|
FTC_Node* bucket;
|
|
|
|
FTC_Node* pnode;
|
|
|
|
FTC_Node node;
|
2013-03-14 11:21:17 +01:00
|
|
|
FT_Error error = FT_Err_Ok;
|
[cache] Notice if a cache query induced the node list change.
Some node comparators (comparing the cache node content and
the properties specified by the query) can flush the cache
node to prevent the cache inflation. The change may
invalidate the pointers to the node obtained before the node
comparison, so the change should be noticed to the caller.
The problem caused by the cache node changing is reported by
Harsha, see Savannah bug #31923.
* src/cache/ftccache.h (FTC_Node_CompareFunc): Add new
argument `FT_Bool* list_changed' to indicate the change of
the cached nodes to the caller.
(FTC_CACHE_LOOKUP_CMP): Watch the change of the cached nodes
by `_list_changed'.
(FTC_CACHE_TRYLOOP_END): Take new macro argument `_list_changed'
and update it when FTC_Manager_FlushN() flushes any nodes.
* src/cache/ftccback.h (ftc_snode_compare): Updated to fit
with new FTC_Node_CompareFunc type. (ftc_gnode_compare): Ditto.
* src/cache/ftcbasic.c: Include FT_INTERNAL_OBJECTS_H to
use TRUE/FALSE macros. (ftc_basic_gnode_compare_faceid):
New argument `FT_Bool* list_changed' to indicate the change
of the cache nodes, anyway, it is always FALSE.
* src/cache/ftccmap.c: Include FT_INTERNAL_OBJECTS_H to
use TRUE/FALSE macros. (ftc_cmap_node_compare):
New argument `FT_Bool* list_changed' to indicate the change
of the cache nodes, anyway, it is always FALSE.
(ftc_cmap_node_remove_faceid): Ditto.
* src/cache/ftccache.c (FTC_Cache_NewNode): Pass a NULL
pointer to FTC_CACHE_TRYLOOP_END(), because the result is
not needed. (FTC_Cache_Lookup): Watch the change of the cache
nodes by `list_changed'. (FTC_Cache_RemoveFaceID): Ditto.
* src/cache/ftcglyph.c: Include FT_INTERNAL_OBJECTS_H to
use TRUE/FALSE macros. (ftc_gnode_compare): New argument
`FT_Bool* list_changed' to indicate the change of the cache
nodes, anyway, it is always FALSE. (FTC_GNode_Compare):
New argument `FT_Bool* list_changed' to be passed to
ftc_gnode_compare().
* src/cache/ftcglyph.h (FTC_GNode_Compare): Ditto.
* src/cache/ftcsbits.c (ftc_snode_compare): New argument
`FT_Bool* list_changed' to indicate the change of the cache
nodes, anyway. It is updated by FTC_CACHE_TRYLOOP().
(FTC_SNode_Compare): New argument `FT_Bool* list_changed'
to be passed to ftc_snode_compare().
* src/cache/ftcsbits.h (FTC_SNode_Compare): Ditto.
2011-01-09 14:49:07 +01:00
|
|
|
FT_Bool list_changed = FALSE;
|
2003-12-24 14:37:58 +01:00
|
|
|
|
|
|
|
FTC_Node_CompareFunc compare = cache->clazz.node_compare;
|
|
|
|
|
|
|
|
|
2016-12-26 17:08:17 +01:00
|
|
|
if ( !cache || !anode )
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Invalid_Argument );
|
2003-12-24 14:37:58 +01:00
|
|
|
|
2011-01-09 15:09:36 +01:00
|
|
|
/* Go to the `top' node of the list sharing same masked hash */
|
2016-01-12 21:40:53 +01:00
|
|
|
bucket = pnode = FTC_NODE_TOP_FOR_HASH( cache, hash );
|
2011-01-09 15:09:36 +01:00
|
|
|
|
|
|
|
/* Lookup a node with exactly same hash and queried properties. */
|
|
|
|
/* NOTE: _nodcomp() may change the linked list to reduce memory. */
|
2003-12-24 14:37:58 +01:00
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
node = *pnode;
|
2016-12-26 17:08:17 +01:00
|
|
|
if ( !node )
|
2003-12-24 14:37:58 +01:00
|
|
|
goto NewNode;
|
|
|
|
|
2011-01-13 10:33:04 +01:00
|
|
|
if ( node->hash == hash &&
|
[cache] Notice if a cache query induced the node list change.
Some node comparators (comparing the cache node content and
the properties specified by the query) can flush the cache
node to prevent the cache inflation. The change may
invalidate the pointers to the node obtained before the node
comparison, so the change should be noticed to the caller.
The problem caused by the cache node changing is reported by
Harsha, see Savannah bug #31923.
* src/cache/ftccache.h (FTC_Node_CompareFunc): Add new
argument `FT_Bool* list_changed' to indicate the change of
the cached nodes to the caller.
(FTC_CACHE_LOOKUP_CMP): Watch the change of the cached nodes
by `_list_changed'.
(FTC_CACHE_TRYLOOP_END): Take new macro argument `_list_changed'
and update it when FTC_Manager_FlushN() flushes any nodes.
* src/cache/ftccback.h (ftc_snode_compare): Updated to fit
with new FTC_Node_CompareFunc type. (ftc_gnode_compare): Ditto.
* src/cache/ftcbasic.c: Include FT_INTERNAL_OBJECTS_H to
use TRUE/FALSE macros. (ftc_basic_gnode_compare_faceid):
New argument `FT_Bool* list_changed' to indicate the change
of the cache nodes, anyway, it is always FALSE.
* src/cache/ftccmap.c: Include FT_INTERNAL_OBJECTS_H to
use TRUE/FALSE macros. (ftc_cmap_node_compare):
New argument `FT_Bool* list_changed' to indicate the change
of the cache nodes, anyway, it is always FALSE.
(ftc_cmap_node_remove_faceid): Ditto.
* src/cache/ftccache.c (FTC_Cache_NewNode): Pass a NULL
pointer to FTC_CACHE_TRYLOOP_END(), because the result is
not needed. (FTC_Cache_Lookup): Watch the change of the cache
nodes by `list_changed'. (FTC_Cache_RemoveFaceID): Ditto.
* src/cache/ftcglyph.c: Include FT_INTERNAL_OBJECTS_H to
use TRUE/FALSE macros. (ftc_gnode_compare): New argument
`FT_Bool* list_changed' to indicate the change of the cache
nodes, anyway, it is always FALSE. (FTC_GNode_Compare):
New argument `FT_Bool* list_changed' to be passed to
ftc_gnode_compare().
* src/cache/ftcglyph.h (FTC_GNode_Compare): Ditto.
* src/cache/ftcsbits.c (ftc_snode_compare): New argument
`FT_Bool* list_changed' to indicate the change of the cache
nodes, anyway. It is updated by FTC_CACHE_TRYLOOP().
(FTC_SNode_Compare): New argument `FT_Bool* list_changed'
to be passed to ftc_snode_compare().
* src/cache/ftcsbits.h (FTC_SNode_Compare): Ditto.
2011-01-09 14:49:07 +01:00
|
|
|
compare( node, query, cache, &list_changed ) )
|
2003-12-24 14:37:58 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
pnode = &node->link;
|
|
|
|
}
|
|
|
|
|
2011-01-09 15:09:36 +01:00
|
|
|
if ( list_changed )
|
|
|
|
{
|
|
|
|
/* Update bucket by modified linked list */
|
2016-01-12 21:40:53 +01:00
|
|
|
bucket = pnode = FTC_NODE_TOP_FOR_HASH( cache, hash );
|
2011-01-09 15:09:36 +01:00
|
|
|
|
|
|
|
/* Update pnode by modified linked list */
|
|
|
|
while ( *pnode != node )
|
|
|
|
{
|
2016-12-26 17:08:17 +01:00
|
|
|
if ( !*pnode )
|
2011-01-09 15:09:36 +01:00
|
|
|
{
|
2011-01-13 10:33:04 +01:00
|
|
|
FT_ERROR(( "FTC_Cache_Lookup: oops!!! node missing\n" ));
|
2011-01-09 15:09:36 +01:00
|
|
|
goto NewNode;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pnode = &((*pnode)->link);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reorder the list to move the found node to the `top' */
|
2003-12-24 14:37:58 +01:00
|
|
|
if ( node != *bucket )
|
|
|
|
{
|
|
|
|
*pnode = node->link;
|
|
|
|
node->link = *bucket;
|
|
|
|
*bucket = node;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* move to head of MRU list */
|
|
|
|
{
|
|
|
|
FTC_Manager manager = cache->manager;
|
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
|
2003-12-24 14:37:58 +01:00
|
|
|
if ( node != manager->nodes_list )
|
|
|
|
ftc_node_mru_up( node, manager );
|
|
|
|
}
|
|
|
|
*anode = node;
|
2011-01-13 10:33:04 +01:00
|
|
|
|
2003-12-24 14:37:58 +01:00
|
|
|
return error;
|
|
|
|
|
|
|
|
NewNode:
|
|
|
|
return FTC_Cache_NewNode( cache, hash, query, anode );
|
|
|
|
}
|
|
|
|
|
* src/cache/ftccache.c, (ftc_node_mru_up, FTC_Cache_Lookup)
[!FTC_INLINE]: Compile conditionally.
* src/cache/ftccache.h: Updated.
* src/cache/ftcglyph.c (FTC_GNode_Init, FTC_GNode_UnselectFamily,
FTC_GNode_Done, FTC_GNode_Compare, FTC_Family_Init, FTC_GCache_New):
s/FT_EXPORT/FT_LOCAL/.
(FTC_GCache_Init, FTC_GCache_Done): Commented out.
(FTC_GCache_Lookup) [!FTC_INLINE]: Compile conditionally.
s/FT_EXPORT/FT_LOCAL/.
* src/cache/ftcglyph.h: Updated.
* src/cache/ftcimage.c (FTC_INode_Free, FTC_INode_New):
s/FT_EXPORT/FT_LOCAL/.
(FTC_INode_Weight): Commented out.
* src/cache/ftcimage.h: Updated.
* src/cache/ftmanag.c (FTC_Manager_Compress,
FTC_Manager_RegisterCache, FTC_Manager_FlushN):
s/FT_EXPORT/FT_LOCAL/.
* src/cache/ftmanag.h: Updated.
* src/cache/ftcsbits.c (FTC_SNode_Free, FTC_SNode_New,
FTC_SNode_Compare): s/FT_EXPORT/FT_LOCAL/.
(FTC_SNode_Weight): Commented out.
* src/cache/ftcsbits.h: Updated.
2006-03-22 16:30:41 +01:00
|
|
|
#endif /* !FTC_INLINE */
|
|
|
|
|
2003-12-24 14:37:58 +01:00
|
|
|
|
* include/freetype/cache/ftccache.h,
include/freetype/cache/ftccmap.h,
include/freetype/cache/ftcglyph.h
include/freetype/cache/ftcimage.h
include/freetype/cache/ftcmanag.h
include/freetype/cache/ftcmru.h
include/freetype/cache/ftcsbits.h:
removing these header files from the public include directory.
* include/freetype/config/ftheader.h:
changing the definition of FT_CACHE_INTERNAL_XXX_H macros to
redirect to FT_CACHE_H instead
* src/cache/ftcbasic.c, src/cache/ftccache.c, src/cache/ftccache.h,
src/cache/ftccback.h, src/cache/ftccmap.c, src/cache/ftcglyph.c,
src/cache/ftcglyph.h, src/cache/ftcimage.c, src/cache/ftcimage.h,
src/cache/ftcmanag.c, src/cache/ftcmanag.h, src/cache/ftcmru.c,
src/cache/ftcmru.h, src/cache/ftcsbits.c, src/cache/ftcsbits.h:
modifications to prevent using the FT_CACHE_INTERNAL_XXX_H macros,
and grab the headers in 'src/cache' instead (see below).
2006-03-20 13:10:24 +01:00
|
|
|
FT_LOCAL_DEF( void )
|
2003-12-26 08:26:08 +01:00
|
|
|
FTC_Cache_RemoveFaceID( FTC_Cache cache,
|
|
|
|
FTC_FaceID face_id )
|
2003-12-24 14:37:58 +01:00
|
|
|
{
|
|
|
|
FT_UFast i, count;
|
|
|
|
FTC_Manager manager = cache->manager;
|
2003-12-24 19:42:04 +01:00
|
|
|
FTC_Node frees = NULL;
|
2003-12-24 14:37:58 +01:00
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
|
2011-02-20 11:13:25 +01:00
|
|
|
count = cache->p + cache->mask + 1;
|
2003-12-24 14:37:58 +01:00
|
|
|
for ( i = 0; i < count; i++ )
|
|
|
|
{
|
|
|
|
FTC_Node* bucket = cache->buckets + i;
|
|
|
|
FTC_Node* pnode = bucket;
|
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
|
2015-10-31 19:08:27 +01:00
|
|
|
for (;;)
|
2003-12-24 14:37:58 +01:00
|
|
|
{
|
|
|
|
FTC_Node node = *pnode;
|
[cache] Notice if a cache query induced the node list change.
Some node comparators (comparing the cache node content and
the properties specified by the query) can flush the cache
node to prevent the cache inflation. The change may
invalidate the pointers to the node obtained before the node
comparison, so the change should be noticed to the caller.
The problem caused by the cache node changing is reported by
Harsha, see Savannah bug #31923.
* src/cache/ftccache.h (FTC_Node_CompareFunc): Add new
argument `FT_Bool* list_changed' to indicate the change of
the cached nodes to the caller.
(FTC_CACHE_LOOKUP_CMP): Watch the change of the cached nodes
by `_list_changed'.
(FTC_CACHE_TRYLOOP_END): Take new macro argument `_list_changed'
and update it when FTC_Manager_FlushN() flushes any nodes.
* src/cache/ftccback.h (ftc_snode_compare): Updated to fit
with new FTC_Node_CompareFunc type. (ftc_gnode_compare): Ditto.
* src/cache/ftcbasic.c: Include FT_INTERNAL_OBJECTS_H to
use TRUE/FALSE macros. (ftc_basic_gnode_compare_faceid):
New argument `FT_Bool* list_changed' to indicate the change
of the cache nodes, anyway, it is always FALSE.
* src/cache/ftccmap.c: Include FT_INTERNAL_OBJECTS_H to
use TRUE/FALSE macros. (ftc_cmap_node_compare):
New argument `FT_Bool* list_changed' to indicate the change
of the cache nodes, anyway, it is always FALSE.
(ftc_cmap_node_remove_faceid): Ditto.
* src/cache/ftccache.c (FTC_Cache_NewNode): Pass a NULL
pointer to FTC_CACHE_TRYLOOP_END(), because the result is
not needed. (FTC_Cache_Lookup): Watch the change of the cache
nodes by `list_changed'. (FTC_Cache_RemoveFaceID): Ditto.
* src/cache/ftcglyph.c: Include FT_INTERNAL_OBJECTS_H to
use TRUE/FALSE macros. (ftc_gnode_compare): New argument
`FT_Bool* list_changed' to indicate the change of the cache
nodes, anyway, it is always FALSE. (FTC_GNode_Compare):
New argument `FT_Bool* list_changed' to be passed to
ftc_gnode_compare().
* src/cache/ftcglyph.h (FTC_GNode_Compare): Ditto.
* src/cache/ftcsbits.c (ftc_snode_compare): New argument
`FT_Bool* list_changed' to indicate the change of the cache
nodes, anyway. It is updated by FTC_CACHE_TRYLOOP().
(FTC_SNode_Compare): New argument `FT_Bool* list_changed'
to be passed to ftc_snode_compare().
* src/cache/ftcsbits.h (FTC_SNode_Compare): Ditto.
2011-01-09 14:49:07 +01:00
|
|
|
FT_Bool list_changed = FALSE;
|
2003-12-24 14:37:58 +01:00
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
|
2016-12-26 17:08:17 +01:00
|
|
|
if ( !node )
|
2003-12-24 14:37:58 +01:00
|
|
|
break;
|
|
|
|
|
2011-01-13 10:33:04 +01:00
|
|
|
if ( cache->clazz.node_remove_faceid( node, face_id,
|
|
|
|
cache, &list_changed ) )
|
2003-12-24 14:37:58 +01:00
|
|
|
{
|
2003-12-26 08:26:08 +01:00
|
|
|
*pnode = node->link;
|
2003-12-24 19:42:04 +01:00
|
|
|
node->link = frees;
|
|
|
|
frees = node;
|
2003-12-24 14:37:58 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
pnode = &node->link;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
/* remove all nodes in the free list */
|
2003-12-24 19:42:04 +01:00
|
|
|
while ( frees )
|
2003-12-24 14:37:58 +01:00
|
|
|
{
|
|
|
|
FTC_Node node;
|
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
|
2003-12-24 19:42:04 +01:00
|
|
|
node = frees;
|
|
|
|
frees = node->link;
|
2003-12-24 14:37:58 +01:00
|
|
|
|
|
|
|
manager->cur_weight -= cache->clazz.node_weight( node, cache );
|
|
|
|
ftc_node_mru_unlink( node, manager );
|
|
|
|
|
|
|
|
cache->clazz.node_free( node, cache );
|
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
cache->slack++;
|
2003-12-24 14:37:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
ftc_cache_resize( cache );
|
|
|
|
}
|
|
|
|
|
2003-12-26 08:26:08 +01:00
|
|
|
|
2003-12-24 14:37:58 +01:00
|
|
|
/* END */
|