📄 ftcmru.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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -