~ubuntu-branches/ubuntu/saucy/emscripten/saucy-proposed

« back to all changes in this revision

Viewing changes to tests/freetype/src/cache/ftcmanag.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

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