~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/3rdparty/freetype/src/cache/ftcmanag.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************/
 
2
/*                                                                         */
 
3
/*  ftcmanag.c                                                             */
 
4
/*                                                                         */
 
5
/*    FreeType Cache Manager (body).                                       */
 
6
/*                                                                         */
 
7
/*  Copyright 2000-2001, 2002, 2003, 2004 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 FT_CACHE_INTERNAL_MANAGER_H
 
22
#include FT_INTERNAL_OBJECTS_H
 
23
#include FT_INTERNAL_DEBUG_H
 
24
#include FT_SIZES_H
 
25
 
 
26
#include "ftcerror.h"
 
27
 
 
28
 
 
29
#undef  FT_COMPONENT
 
30
#define FT_COMPONENT  trace_cache
 
31
 
 
32
#define FTC_LRU_GET_MANAGER( lru )  ( (FTC_Manager)(lru)->user_data )
 
33
 
 
34
 
 
35
  static FT_Error
 
36
  ftc_scaler_lookup_size( FTC_Manager  manager,
 
37
                          FTC_Scaler   scaler,
 
38
                          FT_Size     *asize )
 
39
  {
 
40
    FT_Face   face;
 
41
    FT_Size   size = NULL;
 
42
    FT_Error  error;
 
43
 
 
44
 
 
45
    error = FTC_Manager_LookupFace( manager, scaler->face_id, &face );
 
46
    if ( error )
 
47
      goto Exit;
 
48
 
 
49
    error = FT_New_Size( face, &size );
 
50
    if ( error )
 
51
      goto Exit;
 
52
 
 
53
    FT_Activate_Size( size );
 
54
 
 
55
    if ( scaler->pixel )
 
56
      error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height );
 
57
    else
 
58
      error = FT_Set_Char_Size( face, scaler->width, scaler->height,
 
59
                                scaler->x_res, scaler->y_res );
 
60
    if ( error )
 
61
    {
 
62
      FT_Done_Size( size );
 
63
      size = NULL;
 
64
    }
 
65
 
 
66
  Exit:
 
67
    *asize = size;
 
68
    return error;
 
69
  }
 
70
 
 
71
 
 
72
  typedef struct  FTC_SizeNodeRec_
 
73
  {
 
74
    FTC_MruNodeRec  node;
 
75
    FT_Size         size;
 
76
    FTC_ScalerRec   scaler;
 
77
 
 
78
  } FTC_SizeNodeRec, *FTC_SizeNode;
 
79
 
 
80
 
 
81
  FT_CALLBACK_DEF( void )
 
82
  ftc_size_node_done( FTC_MruNode  ftcnode,
 
83
                      FT_Pointer   data )
 
84
  {
 
85
    FTC_SizeNode  node = (FTC_SizeNode)ftcnode;
 
86
    FT_Size       size = node->size;
 
87
    FT_UNUSED( data );
 
88
 
 
89
 
 
90
    if ( size )
 
91
      FT_Done_Size( size );
 
92
  }
 
93
 
 
94
 
 
95
  FT_CALLBACK_DEF( FT_Bool )
 
96
  ftc_size_node_compare( FTC_MruNode  ftcnode,
 
97
                         FT_Pointer   ftcscaler )
 
98
  {
 
99
    FTC_SizeNode  node    = (FTC_SizeNode)ftcnode;
 
100
    FTC_Scaler    scaler  = (FTC_Scaler)ftcscaler;
 
101
    FTC_Scaler    scaler0 = &node->scaler;
 
102
 
 
103
 
 
104
    if ( FTC_SCALER_COMPARE( scaler0, scaler ) )
 
105
    {
 
106
      FT_Activate_Size( node->size );
 
107
      return 1;
 
108
    }
 
109
    return 0;
 
110
  }
 
111
 
 
112
 
 
113
  FT_CALLBACK_DEF( FT_Error )
 
114
  ftc_size_node_init( FTC_MruNode  ftcnode,
 
115
                      FT_Pointer   ftcscaler,
 
116
                      FT_Pointer   ftcmanager )
 
117
  {
 
118
    FTC_SizeNode  node    = (FTC_SizeNode)ftcnode;
 
119
    FTC_Scaler    scaler  = (FTC_Scaler)ftcscaler;
 
120
    FTC_Manager   manager = (FTC_Manager)ftcmanager;
 
121
 
 
122
 
 
123
    node->scaler = scaler[0];
 
124
 
 
125
    return ftc_scaler_lookup_size( manager, scaler, &node->size );
 
126
  }
 
127
 
 
128
 
 
129
  FT_CALLBACK_DEF( FT_Error )
 
130
  ftc_size_node_reset( FTC_MruNode  ftcnode,
 
131
                       FT_Pointer   ftcscaler,
 
132
                       FT_Pointer   ftcmanager )
 
133
  {
 
134
    FTC_SizeNode  node    = (FTC_SizeNode)ftcnode;
 
135
    FTC_Scaler    scaler  = (FTC_Scaler)ftcscaler;
 
136
    FTC_Manager   manager = (FTC_Manager)ftcmanager;
 
137
 
 
138
 
 
139
    FT_Done_Size( node->size );
 
140
 
 
141
    node->scaler = scaler[0];
 
142
 
 
143
    return ftc_scaler_lookup_size( manager, scaler, &node->size );
 
144
  }
 
145
 
 
146
 
 
147
  FT_CALLBACK_TABLE_DEF
 
148
  const FTC_MruListClassRec  ftc_size_list_class =
 
149
  {
 
150
    sizeof ( FTC_SizeNodeRec ),
 
151
    ftc_size_node_compare,
 
152
    ftc_size_node_init,
 
153
    ftc_size_node_reset,
 
154
    ftc_size_node_done
 
155
  };
 
156
 
 
157
 
 
158
  /* helper function used by ftc_face_node_done */
 
159
  static FT_Bool
 
160
  ftc_size_node_compare_faceid( FTC_MruNode  ftcnode,
 
161
                                FT_Pointer   ftcface_id )
 
162
  {
 
163
    FTC_SizeNode  node    = (FTC_SizeNode)ftcnode;
 
164
    FTC_FaceID    face_id = (FTC_FaceID)ftcface_id;
 
165
 
 
166
 
 
167
    return node->scaler.face_id == face_id;
 
168
  }
 
169
 
 
170
 
 
171
  /* documentation is in ftcache.h */
 
172
 
 
173
  FT_EXPORT_DEF( FT_Error )
 
174
  FTC_Manager_LookupSize( FTC_Manager  manager,
 
175
                          FTC_Scaler   scaler,
 
176
                          FT_Size     *asize )
 
177
  {
 
178
    FT_Error      error;
 
179
    FTC_SizeNode  node;
 
180
 
 
181
 
 
182
    if ( asize == NULL )
 
183
      return FTC_Err_Bad_Argument;
 
184
 
 
185
    *asize = NULL;
 
186
 
 
187
    if ( !manager )
 
188
      return FTC_Err_Invalid_Cache_Handle;
 
189
 
 
190
#ifdef FTC_INLINE
 
191
 
 
192
    FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_compare,
 
193
                            node, error );
 
194
 
 
195
#else
 
196
    error = FTC_MruList_Lookup( &manager->sizes, scaler, (FTC_MruNode*)&node );
 
197
#endif
 
198
 
 
199
    if ( !error )
 
200
      *asize = node->size;
 
201
 
 
202
    return error;
 
203
  }
 
204
 
 
205
 
 
206
  /*************************************************************************/
 
207
  /*************************************************************************/
 
208
  /*****                                                               *****/
 
209
  /*****                    FACE MRU IMPLEMENTATION                    *****/
 
210
  /*****                                                               *****/
 
211
  /*************************************************************************/
 
212
  /*************************************************************************/
 
213
 
 
214
  typedef struct  FTC_FaceNodeRec_
 
215
  {
 
216
    FTC_MruNodeRec  node;
 
217
    FTC_FaceID      face_id;
 
218
    FT_Face         face;
 
219
 
 
220
  } FTC_FaceNodeRec, *FTC_FaceNode;
 
221
 
 
222
 
 
223
  FT_CALLBACK_DEF( FT_Error )
 
224
  ftc_face_node_init( FTC_MruNode  ftcnode,
 
225
                      FT_Pointer   ftcface_id,
 
226
                      FT_Pointer   ftcmanager )
 
227
  {
 
228
    FTC_FaceNode  node    = (FTC_FaceNode)ftcnode;
 
229
    FTC_FaceID    face_id = (FTC_FaceID)ftcface_id;
 
230
    FTC_Manager   manager = (FTC_Manager)ftcmanager;
 
231
    FT_Error      error;
 
232
 
 
233
 
 
234
    node->face_id = face_id;
 
235
 
 
236
    error = manager->request_face( face_id,
 
237
                                   manager->library,
 
238
                                   manager->request_data,
 
239
                                   &node->face );
 
240
    if ( !error )
 
241
    {
 
242
      /* destroy initial size object; it will be re-created later */
 
243
      if ( node->face->size )
 
244
        FT_Done_Size( node->face->size );
 
245
    }
 
246
 
 
247
    return error;
 
248
  }
 
249
 
 
250
 
 
251
  FT_CALLBACK_DEF( void )
 
252
  ftc_face_node_done( FTC_MruNode  ftcnode,
 
253
                      FT_Pointer   ftcmanager )
 
254
  {
 
255
    FTC_FaceNode  node    = (FTC_FaceNode)ftcnode;
 
256
    FTC_Manager   manager = (FTC_Manager)ftcmanager;
 
257
 
 
258
 
 
259
    /* we must begin by removing all scalers for the target face */
 
260
    /* from the manager's list                                   */
 
261
    FTC_MruList_RemoveSelection( &manager->sizes,
 
262
                                 ftc_size_node_compare_faceid,
 
263
                                 node->face_id );
 
264
 
 
265
    /* all right, we can discard the face now */
 
266
    FT_Done_Face( node->face );
 
267
    node->face    = NULL;
 
268
    node->face_id = NULL;
 
269
  }
 
270
 
 
271
 
 
272
  FT_CALLBACK_DEF( FT_Bool )
 
273
  ftc_face_node_compare( FTC_MruNode  ftcnode,
 
274
                         FT_Pointer   ftcface_id )
 
275
  {
 
276
    FTC_FaceNode  node    = (FTC_FaceNode)ftcnode;
 
277
    FTC_FaceID    face_id = (FTC_FaceID)ftcface_id;
 
278
 
 
279
 
 
280
    return FT_BOOL( node->face_id == face_id );
 
281
  }
 
282
 
 
283
 
 
284
  FT_CALLBACK_TABLE_DEF
 
285
  const FTC_MruListClassRec  ftc_face_list_class =
 
286
  {
 
287
    sizeof ( FTC_FaceNodeRec),
 
288
 
 
289
    ftc_face_node_compare,
 
290
    ftc_face_node_init,
 
291
    0,                          /* FTC_MruNode_ResetFunc */
 
292
    ftc_face_node_done
 
293
  };
 
294
 
 
295
 
 
296
  /* documentation is in ftcache.h */
 
297
 
 
298
  FT_EXPORT_DEF( FT_Error )
 
299
  FTC_Manager_LookupFace( FTC_Manager  manager,
 
300
                          FTC_FaceID   face_id,
 
301
                          FT_Face     *aface )
 
302
  {
 
303
    FT_Error      error;
 
304
    FTC_FaceNode  node;
 
305
 
 
306
 
 
307
    if ( aface == NULL )
 
308
      return FTC_Err_Bad_Argument;
 
309
 
 
310
    *aface = NULL;
 
311
 
 
312
    if ( !manager )
 
313
      return FTC_Err_Invalid_Cache_Handle;
 
314
 
 
315
    /* we break encapsulation for the sake of speed */
 
316
#ifdef FTC_INLINE
 
317
 
 
318
    FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_compare,
 
319
                            node, error );
 
320
 
 
321
#else
 
322
    error = FTC_MruList_Lookup( &manager->faces, face_id, (FTC_MruNode*)&node );
 
323
#endif
 
324
 
 
325
    if ( !error )
 
326
      *aface = node->face;
 
327
 
 
328
    return error;
 
329
  }
 
330
 
 
331
 
 
332
  /*************************************************************************/
 
333
  /*************************************************************************/
 
334
  /*****                                                               *****/
 
335
  /*****                    CACHE MANAGER ROUTINES                     *****/
 
336
  /*****                                                               *****/
 
337
  /*************************************************************************/
 
338
  /*************************************************************************/
 
339
 
 
340
 
 
341
  /* documentation is in ftcache.h */
 
342
 
 
343
  FT_EXPORT_DEF( FT_Error )
 
344
  FTC_Manager_New( FT_Library          library,
 
345
                   FT_UInt             max_faces,
 
346
                   FT_UInt             max_sizes,
 
347
                   FT_ULong            max_bytes,
 
348
                   FTC_Face_Requester  requester,
 
349
                   FT_Pointer          req_data,
 
350
                   FTC_Manager        *amanager )
 
351
  {
 
352
    FT_Error     error;
 
353
    FT_Memory    memory;
 
354
    FTC_Manager  manager = 0;
 
355
 
 
356
 
 
357
    if ( !library )
 
358
      return FTC_Err_Invalid_Library_Handle;
 
359
 
 
360
    memory = library->memory;
 
361
 
 
362
    if ( FT_NEW( manager ) )
 
363
      goto Exit;
 
364
 
 
365
    if ( max_faces == 0 )
 
366
      max_faces = FTC_MAX_FACES_DEFAULT;
 
367
 
 
368
    if ( max_sizes == 0 )
 
369
      max_sizes = FTC_MAX_SIZES_DEFAULT;
 
370
 
 
371
    if ( max_bytes == 0 )
 
372
      max_bytes = FTC_MAX_BYTES_DEFAULT;
 
373
 
 
374
    manager->library      = library;
 
375
    manager->memory       = memory;
 
376
    manager->max_weight   = max_bytes;
 
377
 
 
378
    manager->request_face = requester;
 
379
    manager->request_data = req_data;
 
380
 
 
381
    FTC_MruList_Init( &manager->faces,
 
382
                      &ftc_face_list_class,
 
383
                      max_faces,
 
384
                      manager,
 
385
                      memory );
 
386
 
 
387
    FTC_MruList_Init( &manager->sizes,
 
388
                      &ftc_size_list_class,
 
389
                      max_sizes,
 
390
                      manager,
 
391
                      memory );
 
392
 
 
393
    *amanager = manager;
 
394
 
 
395
  Exit:
 
396
    return error;
 
397
  }
 
398
 
 
399
 
 
400
  /* documentation is in ftcache.h */
 
401
 
 
402
  FT_EXPORT_DEF( void )
 
403
  FTC_Manager_Done( FTC_Manager  manager )
 
404
  {
 
405
    FT_Memory  memory;
 
406
    FT_UInt    idx;
 
407
 
 
408
 
 
409
    if ( !manager || !manager->library )
 
410
      return;
 
411
 
 
412
    memory = manager->memory;
 
413
 
 
414
    /* now discard all caches */
 
415
    for (idx = manager->num_caches; idx-- > 0; )
 
416
    {
 
417
      FTC_Cache  cache = manager->caches[idx];
 
418
 
 
419
 
 
420
      if ( cache )
 
421
      {
 
422
        cache->clazz.cache_done( cache );
 
423
        FT_FREE( cache );
 
424
        manager->caches[idx] = NULL;
 
425
      }
 
426
    }
 
427
    manager->num_caches = 0;
 
428
 
 
429
    /* discard faces and sizes */
 
430
    FTC_MruList_Done( &manager->sizes );
 
431
    FTC_MruList_Done( &manager->faces );
 
432
 
 
433
    manager->library = NULL;
 
434
    manager->memory  = NULL;
 
435
 
 
436
    FT_FREE( manager );
 
437
  }
 
438
 
 
439
 
 
440
  /* documentation is in ftcache.h */
 
441
 
 
442
  FT_EXPORT_DEF( void )
 
443
  FTC_Manager_Reset( FTC_Manager  manager )
 
444
  {
 
445
    if ( manager )
 
446
    {
 
447
      FTC_MruList_Reset( &manager->sizes );
 
448
      FTC_MruList_Reset( &manager->faces );
 
449
    }
 
450
    /* XXX: FIXME: flush the caches? */
 
451
  }
 
452
 
 
453
 
 
454
#ifdef FT_DEBUG_ERROR
 
455
 
 
456
  FT_EXPORT_DEF( void )
 
457
  FTC_Manager_Check( FTC_Manager  manager )
 
458
  {
 
459
    FTC_Node  node, first;
 
460
 
 
461
 
 
462
    first = manager->nodes_list;
 
463
 
 
464
    /* check node weights */
 
465
    if ( first )
 
466
    {
 
467
      FT_ULong  weight = 0;
 
468
 
 
469
 
 
470
      node = first;
 
471
 
 
472
      do
 
473
      {
 
474
        FTC_Cache  cache = manager->caches[node->cache_index];
 
475
 
 
476
 
 
477
        if ( (FT_UInt)node->cache_index >= manager->num_caches )
 
478
          FT_ERROR(( "FTC_Manager_Check: invalid node (cache index = %ld\n",
 
479
                     node->cache_index ));
 
480
        else
 
481
          weight += cache->clazz.node_weight( node, cache );
 
482
 
 
483
        node = FTC_NODE__NEXT( node );
 
484
 
 
485
      } while ( node != first );
 
486
 
 
487
      if ( weight != manager->cur_weight )
 
488
        FT_ERROR(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n",
 
489
                   manager->cur_weight, weight ));
 
490
    }
 
491
 
 
492
    /* check circular list */
 
493
    if ( first )
 
494
    {
 
495
      FT_UFast  count = 0;
 
496
 
 
497
 
 
498
      node = first;
 
499
      do
 
500
      {
 
501
        count++;
 
502
        node = FTC_NODE__NEXT( node );
 
503
 
 
504
      } while ( node != first );
 
505
 
 
506
      if ( count != manager->num_nodes )
 
507
        FT_ERROR((
 
508
          "FTC_Manager_Check: invalid cache node count %d instead of %d\n",
 
509
          manager->num_nodes, count ));
 
510
    }
 
511
  }
 
512
 
 
513
#endif /* FT_DEBUG_ERROR */
 
514
 
 
515
 
 
516
  /* `Compress' the manager's data, i.e., get rid of old cache nodes */
 
517
  /* that are not referenced anymore in order to limit the total     */
 
518
  /* memory used by the cache.                                       */
 
519
 
 
520
  /* documentation is in ftcmanag.h */
 
521
 
 
522
  FT_EXPORT_DEF( void )
 
523
  FTC_Manager_Compress( FTC_Manager  manager )
 
524
  {
 
525
    FTC_Node   node, first;
 
526
 
 
527
 
 
528
    if ( !manager )
 
529
      return;
 
530
 
 
531
    first = manager->nodes_list;
 
532
 
 
533
#ifdef FT_DEBUG_ERROR
 
534
    FTC_Manager_Check( manager );
 
535
 
 
536
    FT_ERROR(( "compressing, weight = %ld, max = %ld, nodes = %d\n",
 
537
               manager->cur_weight, manager->max_weight,
 
538
               manager->num_nodes ));
 
539
#endif
 
540
 
 
541
    if ( manager->cur_weight < manager->max_weight || first == NULL )
 
542
      return;
 
543
 
 
544
    /* go to last node -- it's a circular list */
 
545
    node = FTC_NODE__PREV( first );
 
546
    do
 
547
    {
 
548
      FTC_Node  prev;
 
549
 
 
550
 
 
551
      prev = ( node == first ) ? NULL : FTC_NODE__PREV( node );
 
552
 
 
553
      if ( node->ref_count <= 0 )
 
554
        ftc_node_destroy( node, manager );
 
555
 
 
556
      node = prev;
 
557
 
 
558
    } while ( node && manager->cur_weight > manager->max_weight );
 
559
  }
 
560
 
 
561
 
 
562
  /* documentation is in ftcmanag.h */
 
563
 
 
564
  FT_EXPORT_DEF( FT_Error )
 
565
  FTC_Manager_RegisterCache( FTC_Manager      manager,
 
566
                             FTC_CacheClass   clazz,
 
567
                             FTC_Cache       *acache )
 
568
  {
 
569
    FT_Error   error = FTC_Err_Invalid_Argument;
 
570
    FTC_Cache  cache = NULL;
 
571
 
 
572
 
 
573
    if ( manager && clazz && acache )
 
574
    {
 
575
      FT_Memory  memory = manager->memory;
 
576
 
 
577
 
 
578
      if ( manager->num_caches >= FTC_MAX_CACHES )
 
579
      {
 
580
        error = FTC_Err_Too_Many_Caches;
 
581
        FT_ERROR(( "%s: too many registered caches\n",
 
582
                   "FTC_Manager_Register_Cache" ));
 
583
        goto Exit;
 
584
      }
 
585
 
 
586
      if ( !FT_ALLOC( cache, clazz->cache_size ) )
 
587
      {
 
588
        cache->manager   = manager;
 
589
        cache->memory    = memory;
 
590
        cache->clazz     = clazz[0];
 
591
        cache->org_class = clazz;
 
592
 
 
593
        /* THIS IS VERY IMPORTANT!  IT WILL WRETCH THE MANAGER */
 
594
        /* IF IT IS NOT SET CORRECTLY                          */
 
595
        cache->index = manager->num_caches;
 
596
 
 
597
        error = clazz->cache_init( cache );
 
598
        if ( error )
 
599
        {
 
600
          clazz->cache_done( cache );
 
601
          FT_FREE( cache );
 
602
          goto Exit;
 
603
        }
 
604
 
 
605
        manager->caches[manager->num_caches++] = cache;
 
606
      }
 
607
    }
 
608
 
 
609
  Exit:
 
610
    *acache = cache;
 
611
    return error;
 
612
  }
 
613
 
 
614
 
 
615
  FT_EXPORT_DEF( FT_UInt )
 
616
  FTC_Manager_FlushN( FTC_Manager  manager,
 
617
                      FT_UInt      count )
 
618
  {
 
619
    FTC_Node  first = manager->nodes_list;
 
620
    FTC_Node  node;
 
621
    FT_UInt   result;
 
622
 
 
623
 
 
624
    /* try to remove `count' nodes from the list */
 
625
    if ( first == NULL )  /* empty list! */
 
626
      return 0;
 
627
 
 
628
    /* go to last node - it's a circular list */
 
629
    node = FTC_NODE__PREV(first);
 
630
    for ( result = 0; result < count; )
 
631
    {
 
632
      FTC_Node  prev = FTC_NODE__PREV( node );
 
633
 
 
634
 
 
635
      /* don't touch locked nodes */
 
636
      if ( node->ref_count <= 0 )
 
637
      {
 
638
        ftc_node_destroy( node, manager );
 
639
        result++;
 
640
      }
 
641
 
 
642
      if ( prev == manager->nodes_list )
 
643
        break;
 
644
 
 
645
      node = prev;
 
646
    }
 
647
    return  result;
 
648
  }
 
649
 
 
650
 
 
651
  /* documentation is in ftcache.h */
 
652
 
 
653
  FT_EXPORT_DEF( void )
 
654
  FTC_Manager_RemoveFaceID( FTC_Manager  manager,
 
655
                            FTC_FaceID   face_id )
 
656
  {
 
657
    FT_UInt  nn;
 
658
 
 
659
    /* this will remove all FTC_SizeNode that correspond to
 
660
     * the face_id as well
 
661
     */
 
662
    FTC_MruList_RemoveSelection( &manager->faces, NULL, face_id );
 
663
 
 
664
    for ( nn = 0; nn < manager->num_caches; nn++ )
 
665
      FTC_Cache_RemoveFaceID( manager->caches[nn], face_id );
 
666
  }
 
667
 
 
668
 
 
669
  /* documentation is in ftcache.h */
 
670
 
 
671
  FT_EXPORT_DEF( void )
 
672
  FTC_Node_Unref( FTC_Node     node,
 
673
                  FTC_Manager  manager )
 
674
  {
 
675
    if ( node && (FT_UInt)node->cache_index < manager->num_caches )
 
676
      node->ref_count--;
 
677
  }
 
678
 
 
679
 
 
680
/* END */