5172
+ − 1
/***************************************************************************/
+ − 2
/* */
+ − 3
/* ftcmru.c */
+ − 4
/* */
+ − 5
/* FreeType MRU support (body). */
+ − 6
/* */
+ − 7
/* Copyright 2003, 2004, 2006, 2009 by */
+ − 8
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ − 9
/* */
+ − 10
/* This file is part of the FreeType project, and may only be used, */
+ − 11
/* modified, and distributed under the terms of the FreeType project */
+ − 12
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+ − 13
/* this file you indicate that you have read the license and */
+ − 14
/* understand and accept it fully. */
+ − 15
/* */
+ − 16
/***************************************************************************/
+ − 17
+ − 18
+ − 19
#include <ft2build.h>
+ − 20
#include FT_CACHE_H
+ − 21
#include "ftcmru.h"
+ − 22
#include FT_INTERNAL_OBJECTS_H
+ − 23
#include FT_INTERNAL_DEBUG_H
+ − 24
+ − 25
#include "ftcerror.h"
+ − 26
+ − 27
+ − 28
FT_LOCAL_DEF( void )
+ − 29
FTC_MruNode_Prepend( FTC_MruNode *plist,
+ − 30
FTC_MruNode node )
+ − 31
{
+ − 32
FTC_MruNode first = *plist;
+ − 33
+ − 34
+ − 35
if ( first )
+ − 36
{
+ − 37
FTC_MruNode last = first->prev;
+ − 38
+ − 39
+ − 40
#ifdef FT_DEBUG_ERROR
+ − 41
{
+ − 42
FTC_MruNode cnode = first;
+ − 43
+ − 44
+ − 45
do
+ − 46
{
+ − 47
if ( cnode == node )
+ − 48
{
+ − 49
fprintf( stderr, "FTC_MruNode_Prepend: invalid action\n" );
+ − 50
exit( 2 );
+ − 51
}
+ − 52
cnode = cnode->next;
+ − 53
+ − 54
} while ( cnode != first );
+ − 55
}
+ − 56
#endif
+ − 57
+ − 58
first->prev = node;
+ − 59
last->next = node;
+ − 60
node->next = first;
+ − 61
node->prev = last;
+ − 62
}
+ − 63
else
+ − 64
{
+ − 65
node->next = node;
+ − 66
node->prev = node;
+ − 67
}
+ − 68
*plist = node;
+ − 69
}
+ − 70
+ − 71
+ − 72
FT_LOCAL_DEF( void )
+ − 73
FTC_MruNode_Up( FTC_MruNode *plist,
+ − 74
FTC_MruNode node )
+ − 75
{
+ − 76
FTC_MruNode first = *plist;
+ − 77
+ − 78
+ − 79
FT_ASSERT( first != NULL );
+ − 80
+ − 81
if ( first != node )
+ − 82
{
+ − 83
FTC_MruNode prev, next, last;
+ − 84
+ − 85
+ − 86
#ifdef FT_DEBUG_ERROR
+ − 87
{
+ − 88
FTC_MruNode cnode = first;
+ − 89
do
+ − 90
{
+ − 91
if ( cnode == node )
+ − 92
goto Ok;
+ − 93
cnode = cnode->next;
+ − 94
+ − 95
} while ( cnode != first );
+ − 96
+ − 97
fprintf( stderr, "FTC_MruNode_Up: invalid action\n" );
+ − 98
exit( 2 );
+ − 99
Ok:
+ − 100
}
+ − 101
#endif
+ − 102
prev = node->prev;
+ − 103
next = node->next;
+ − 104
+ − 105
prev->next = next;
+ − 106
next->prev = prev;
+ − 107
+ − 108
last = first->prev;
+ − 109
+ − 110
last->next = node;
+ − 111
first->prev = node;
+ − 112
+ − 113
node->next = first;
+ − 114
node->prev = last;
+ − 115
+ − 116
*plist = node;
+ − 117
}
+ − 118
}
+ − 119
+ − 120
+ − 121
FT_LOCAL_DEF( void )
+ − 122
FTC_MruNode_Remove( FTC_MruNode *plist,
+ − 123
FTC_MruNode node )
+ − 124
{
+ − 125
FTC_MruNode first = *plist;
+ − 126
FTC_MruNode prev, next;
+ − 127
+ − 128
+ − 129
FT_ASSERT( first != NULL );
+ − 130
+ − 131
#ifdef FT_DEBUG_ERROR
+ − 132
{
+ − 133
FTC_MruNode cnode = first;
+ − 134
+ − 135
+ − 136
do
+ − 137
{
+ − 138
if ( cnode == node )
+ − 139
goto Ok;
+ − 140
cnode = cnode->next;
+ − 141
+ − 142
} while ( cnode != first );
+ − 143
+ − 144
fprintf( stderr, "FTC_MruNode_Remove: invalid action\n" );
+ − 145
exit( 2 );
+ − 146
Ok:
+ − 147
}
+ − 148
#endif
+ − 149
+ − 150
prev = node->prev;
+ − 151
next = node->next;
+ − 152
+ − 153
prev->next = next;
+ − 154
next->prev = prev;
+ − 155
+ − 156
if ( node == next )
+ − 157
{
+ − 158
FT_ASSERT( first == node );
+ − 159
FT_ASSERT( prev == node );
+ − 160
+ − 161
*plist = NULL;
+ − 162
}
+ − 163
else if ( node == first )
+ − 164
*plist = next;
+ − 165
}
+ − 166
+ − 167
+ − 168
FT_LOCAL_DEF( void )
+ − 169
FTC_MruList_Init( FTC_MruList list,
+ − 170
FTC_MruListClass clazz,
+ − 171
FT_UInt max_nodes,
+ − 172
FT_Pointer data,
+ − 173
FT_Memory memory )
+ − 174
{
+ − 175
list->num_nodes = 0;
+ − 176
list->max_nodes = max_nodes;
+ − 177
list->nodes = NULL;
+ − 178
list->clazz = *clazz;
+ − 179
list->data = data;
+ − 180
list->memory = memory;
+ − 181
}
+ − 182
+ − 183
+ − 184
FT_LOCAL_DEF( void )
+ − 185
FTC_MruList_Reset( FTC_MruList list )
+ − 186
{
+ − 187
while ( list->nodes )
+ − 188
FTC_MruList_Remove( list, list->nodes );
+ − 189
+ − 190
FT_ASSERT( list->num_nodes == 0 );
+ − 191
}
+ − 192
+ − 193
+ − 194
FT_LOCAL_DEF( void )
+ − 195
FTC_MruList_Done( FTC_MruList list )
+ − 196
{
+ − 197
FTC_MruList_Reset( list );
+ − 198
}
+ − 199
+ − 200
+ − 201
#ifndef FTC_INLINE
+ − 202
FT_LOCAL_DEF( FTC_MruNode )
+ − 203
FTC_MruList_Find( FTC_MruList list,
+ − 204
FT_Pointer key )
+ − 205
{
+ − 206
FTC_MruNode_CompareFunc compare = list->clazz.node_compare;
+ − 207
FTC_MruNode first, node;
+ − 208
+ − 209
+ − 210
first = list->nodes;
+ − 211
node = NULL;
+ − 212
+ − 213
if ( first )
+ − 214
{
+ − 215
node = first;
+ − 216
do
+ − 217
{
+ − 218
if ( compare( node, key ) )
+ − 219
{
+ − 220
if ( node != first )
+ − 221
FTC_MruNode_Up( &list->nodes, node );
+ − 222
+ − 223
return node;
+ − 224
}
+ − 225
+ − 226
node = node->next;
+ − 227
+ − 228
} while ( node != first);
+ − 229
}
+ − 230
+ − 231
return NULL;
+ − 232
}
+ − 233
#endif
+ − 234
+ − 235
FT_LOCAL_DEF( FT_Error )
+ − 236
FTC_MruList_New( FTC_MruList list,
+ − 237
FT_Pointer key,
+ − 238
FTC_MruNode *anode )
+ − 239
{
+ − 240
FT_Error error;
+ − 241
FTC_MruNode node;
+ − 242
FT_Memory memory = list->memory;
+ − 243
+ − 244
+ − 245
if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 )
+ − 246
{
+ − 247
node = list->nodes->prev;
+ − 248
+ − 249
FT_ASSERT( node );
+ − 250
+ − 251
if ( list->clazz.node_reset )
+ − 252
{
+ − 253
FTC_MruNode_Up( &list->nodes, node );
+ − 254
+ − 255
error = list->clazz.node_reset( node, key, list->data );
+ − 256
if ( !error )
+ − 257
goto Exit;
+ − 258
}
+ − 259
+ − 260
FTC_MruNode_Remove( &list->nodes, node );
+ − 261
list->num_nodes--;
+ − 262
+ − 263
if ( list->clazz.node_done )
+ − 264
list->clazz.node_done( node, list->data );
+ − 265
}
+ − 266
else if ( FT_ALLOC( node, list->clazz.node_size ) )
+ − 267
goto Exit;
+ − 268
+ − 269
error = list->clazz.node_init( node, key, list->data );
+ − 270
if ( error )
+ − 271
goto Fail;
+ − 272
+ − 273
FTC_MruNode_Prepend( &list->nodes, node );
+ − 274
list->num_nodes++;
+ − 275
+ − 276
Exit:
+ − 277
*anode = node;
+ − 278
return error;
+ − 279
+ − 280
Fail:
+ − 281
if ( list->clazz.node_done )
+ − 282
list->clazz.node_done( node, list->data );
+ − 283
+ − 284
FT_FREE( node );
+ − 285
goto Exit;
+ − 286
}
+ − 287
+ − 288
+ − 289
#ifndef FTC_INLINE
+ − 290
FT_LOCAL_DEF( FT_Error )
+ − 291
FTC_MruList_Lookup( FTC_MruList list,
+ − 292
FT_Pointer key,
+ − 293
FTC_MruNode *anode )
+ − 294
{
+ − 295
FTC_MruNode node;
+ − 296
+ − 297
+ − 298
node = FTC_MruList_Find( list, key );
+ − 299
if ( node == NULL )
+ − 300
return FTC_MruList_New( list, key, anode );
+ − 301
+ − 302
*anode = node;
+ − 303
return 0;
+ − 304
}
+ − 305
#endif /* FTC_INLINE */
+ − 306
+ − 307
FT_LOCAL_DEF( void )
+ − 308
FTC_MruList_Remove( FTC_MruList list,
+ − 309
FTC_MruNode node )
+ − 310
{
+ − 311
FTC_MruNode_Remove( &list->nodes, node );
+ − 312
list->num_nodes--;
+ − 313
+ − 314
{
+ − 315
FT_Memory memory = list->memory;
+ − 316
+ − 317
+ − 318
if ( list->clazz.node_done )
+ − 319
list->clazz.node_done( node, list->data );
+ − 320
+ − 321
FT_FREE( node );
+ − 322
}
+ − 323
}
+ − 324
+ − 325
+ − 326
FT_LOCAL_DEF( void )
+ − 327
FTC_MruList_RemoveSelection( FTC_MruList list,
+ − 328
FTC_MruNode_CompareFunc selection,
+ − 329
FT_Pointer key )
+ − 330
{
+ − 331
FTC_MruNode first, node, next;
+ − 332
+ − 333
+ − 334
first = list->nodes;
+ − 335
while ( first && ( selection == NULL || selection( first, key ) ) )
+ − 336
{
+ − 337
FTC_MruList_Remove( list, first );
+ − 338
first = list->nodes;
+ − 339
}
+ − 340
+ − 341
if ( first )
+ − 342
{
+ − 343
node = first->next;
+ − 344
while ( node != first )
+ − 345
{
+ − 346
next = node->next;
+ − 347
+ − 348
if ( selection( node, key ) )
+ − 349
FTC_MruList_Remove( list, node );
+ − 350
+ − 351
node = next;
+ − 352
}
+ − 353
}
+ − 354
}
+ − 355
+ − 356
+ − 357
/* END */