misc/libfreetype/src/cache/ftcmanag.c
changeset 9372 915436ff64ab
parent 9371 f3840de881bd
child 9373 b769a8e38cbd
equal deleted inserted replaced
9371:f3840de881bd 9372:915436ff64ab
     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 */