5a73d8d20f
(FREETYPE_H): Updated. * src/cache/rules.mk (CACHE_H_DIR): Remove. (CACHE_DRV_H): Updated. Formatting, copyright years.
358 lines
7.5 KiB
C
358 lines
7.5 KiB
C
/***************************************************************************/
|
|
/* */
|
|
/* ftcmru.c */
|
|
/* */
|
|
/* FreeType MRU support (body). */
|
|
/* */
|
|
/* Copyright 2003, 2004, 2006 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 "ftcmru.h"
|
|
#include FT_INTERNAL_OBJECTS_H
|
|
#include FT_INTERNAL_DEBUG_H
|
|
|
|
#include "ftcerror.h"
|
|
|
|
|
|
FT_LOCAL_DEF( void )
|
|
FTC_MruNode_Prepend( FTC_MruNode *plist,
|
|
FTC_MruNode node )
|
|
{
|
|
FTC_MruNode first = *plist;
|
|
|
|
|
|
if ( first )
|
|
{
|
|
FTC_MruNode last = first->prev;
|
|
|
|
|
|
#ifdef FT_DEBUG_ERROR
|
|
{
|
|
FTC_MruNode cnode = first;
|
|
|
|
|
|
do
|
|
{
|
|
if ( cnode == node )
|
|
{
|
|
fprintf( stderr, "FTC_MruNode_Prepend: invalid action!\n" );
|
|
exit( 2 );
|
|
}
|
|
cnode = cnode->next;
|
|
|
|
} while ( cnode != first );
|
|
}
|
|
#endif
|
|
|
|
first->prev = node;
|
|
last->next = node;
|
|
node->next = first;
|
|
node->prev = last;
|
|
}
|
|
else
|
|
{
|
|
node->next = node;
|
|
node->prev = node;
|
|
}
|
|
*plist = node;
|
|
}
|
|
|
|
|
|
FT_LOCAL_DEF( void )
|
|
FTC_MruNode_Up( FTC_MruNode *plist,
|
|
FTC_MruNode node )
|
|
{
|
|
FTC_MruNode first = *plist;
|
|
|
|
|
|
FT_ASSERT( first != NULL );
|
|
|
|
if ( first != node )
|
|
{
|
|
FTC_MruNode prev, next, last;
|
|
|
|
|
|
#ifdef FT_DEBUG_ERROR
|
|
{
|
|
FTC_MruNode cnode = first;
|
|
do
|
|
{
|
|
if ( cnode == node )
|
|
goto Ok;
|
|
cnode = cnode->next;
|
|
|
|
} while ( cnode != first );
|
|
|
|
fprintf( stderr, "FTC_MruNode_Up: invalid action!\n" );
|
|
exit( 2 );
|
|
Ok:
|
|
}
|
|
#endif
|
|
prev = node->prev;
|
|
next = node->next;
|
|
|
|
prev->next = next;
|
|
next->prev = prev;
|
|
|
|
last = first->prev;
|
|
|
|
last->next = node;
|
|
first->prev = node;
|
|
|
|
node->next = first;
|
|
node->prev = last;
|
|
|
|
*plist = node;
|
|
}
|
|
}
|
|
|
|
|
|
FT_LOCAL_DEF( void )
|
|
FTC_MruNode_Remove( FTC_MruNode *plist,
|
|
FTC_MruNode node )
|
|
{
|
|
FTC_MruNode first = *plist;
|
|
FTC_MruNode prev, next;
|
|
|
|
|
|
FT_ASSERT( first != NULL );
|
|
|
|
#ifdef FT_DEBUG_ERROR
|
|
{
|
|
FTC_MruNode cnode = first;
|
|
|
|
|
|
do
|
|
{
|
|
if ( cnode == node )
|
|
goto Ok;
|
|
cnode = cnode->next;
|
|
|
|
} while ( cnode != first );
|
|
|
|
fprintf( stderr, "FTC_MruNode_Remove: invalid action!\n" );
|
|
exit( 2 );
|
|
Ok:
|
|
}
|
|
#endif
|
|
|
|
prev = node->prev;
|
|
next = node->next;
|
|
|
|
prev->next = next;
|
|
next->prev = prev;
|
|
|
|
if ( node == next )
|
|
{
|
|
FT_ASSERT( first == node );
|
|
FT_ASSERT( prev == node );
|
|
|
|
*plist = NULL;
|
|
}
|
|
else if ( node == first )
|
|
*plist = next;
|
|
}
|
|
|
|
|
|
FT_LOCAL_DEF( void )
|
|
FTC_MruList_Init( FTC_MruList list,
|
|
FTC_MruListClass clazz,
|
|
FT_UInt max_nodes,
|
|
FT_Pointer data,
|
|
FT_Memory memory )
|
|
{
|
|
list->num_nodes = 0;
|
|
list->max_nodes = max_nodes;
|
|
list->nodes = NULL;
|
|
list->clazz = *clazz;
|
|
list->data = data;
|
|
list->memory = memory;
|
|
}
|
|
|
|
|
|
FT_LOCAL_DEF( void )
|
|
FTC_MruList_Reset( FTC_MruList list )
|
|
{
|
|
while ( list->nodes )
|
|
FTC_MruList_Remove( list, list->nodes );
|
|
|
|
FT_ASSERT( list->num_nodes == 0 );
|
|
}
|
|
|
|
|
|
FT_LOCAL_DEF( void )
|
|
FTC_MruList_Done( FTC_MruList list )
|
|
{
|
|
FTC_MruList_Reset( list );
|
|
}
|
|
|
|
|
|
#ifndef FTC_INLINE
|
|
FT_LOCAL_DEF( FTC_MruNode )
|
|
FTC_MruList_Find( FTC_MruList list,
|
|
FT_Pointer key )
|
|
{
|
|
FTC_MruNode_CompareFunc compare = list->clazz.node_compare;
|
|
FTC_MruNode first, node;
|
|
|
|
|
|
first = list->nodes;
|
|
node = NULL;
|
|
|
|
if ( first )
|
|
{
|
|
node = first;
|
|
do
|
|
{
|
|
if ( compare( node, key ) )
|
|
{
|
|
if ( node != first )
|
|
FTC_MruNode_Up( &list->nodes, node );
|
|
|
|
return node;
|
|
}
|
|
|
|
node = node->next;
|
|
|
|
} while ( node != first);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
FT_LOCAL_DEF( FT_Error )
|
|
FTC_MruList_New( FTC_MruList list,
|
|
FT_Pointer key,
|
|
FTC_MruNode *anode )
|
|
{
|
|
FT_Error error;
|
|
FTC_MruNode node;
|
|
FT_Memory memory = list->memory;
|
|
|
|
|
|
if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 )
|
|
{
|
|
node = list->nodes->prev;
|
|
|
|
FT_ASSERT( node );
|
|
|
|
if ( list->clazz.node_reset )
|
|
{
|
|
FTC_MruNode_Up( &list->nodes, node );
|
|
|
|
error = list->clazz.node_reset( node, key, list->data );
|
|
if ( !error )
|
|
goto Exit;
|
|
}
|
|
|
|
FTC_MruNode_Remove( &list->nodes, node );
|
|
list->num_nodes--;
|
|
|
|
if ( list->clazz.node_done )
|
|
list->clazz.node_done( node, list->data );
|
|
}
|
|
else if ( FT_ALLOC( node, list->clazz.node_size ) )
|
|
goto Exit;
|
|
|
|
error = list->clazz.node_init( node, key, list->data );
|
|
if ( error )
|
|
goto Fail;
|
|
|
|
FTC_MruNode_Prepend( &list->nodes, node );
|
|
list->num_nodes++;
|
|
|
|
Exit:
|
|
*anode = node;
|
|
return error;
|
|
|
|
Fail:
|
|
if ( list->clazz.node_done )
|
|
list->clazz.node_done( node, list->data );
|
|
|
|
FT_FREE( node );
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
#ifndef FTC_INLINE
|
|
FT_LOCAL_DEF( FT_Error )
|
|
FTC_MruList_Lookup( FTC_MruList list,
|
|
FT_Pointer key,
|
|
FTC_MruNode *anode )
|
|
{
|
|
FTC_MruNode node;
|
|
|
|
|
|
node = FTC_MruList_Find( list, key );
|
|
if ( node == NULL )
|
|
return FTC_MruList_New( list, key, anode );
|
|
|
|
*anode = node;
|
|
return 0;
|
|
}
|
|
#endif /* FTC_INLINE */
|
|
|
|
FT_LOCAL_DEF( void )
|
|
FTC_MruList_Remove( FTC_MruList list,
|
|
FTC_MruNode node )
|
|
{
|
|
FTC_MruNode_Remove( &list->nodes, node );
|
|
list->num_nodes--;
|
|
|
|
{
|
|
FT_Memory memory = list->memory;
|
|
|
|
|
|
if ( list->clazz.node_done )
|
|
list->clazz.node_done( node, list->data );
|
|
|
|
FT_FREE( node );
|
|
}
|
|
}
|
|
|
|
|
|
FT_LOCAL_DEF( void )
|
|
FTC_MruList_RemoveSelection( FTC_MruList list,
|
|
FTC_MruNode_CompareFunc selection,
|
|
FT_Pointer key )
|
|
{
|
|
FTC_MruNode first, node, next;
|
|
|
|
|
|
first = list->nodes;
|
|
while ( first && ( selection == NULL || selection( first, key ) ) )
|
|
{
|
|
FTC_MruList_Remove( list, first );
|
|
first = list->nodes;
|
|
}
|
|
|
|
if ( first )
|
|
{
|
|
node = first->next;
|
|
while ( node != first )
|
|
{
|
|
next = node->next;
|
|
|
|
if ( selection( node, key ) )
|
|
FTC_MruList_Remove( list, node );
|
|
|
|
node = next;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* END */
|