29#define FT_COMPONENT cache
33 ftc_scaler_lookup_size( FTC_Manager manager,
42 error = FTC_Manager_LookupFace( manager, scaler->face_id, &face );
46 error = FT_New_Size( face, &size );
50 FT_Activate_Size( size );
53 error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height );
55 error = FT_Set_Char_Size( face,
56 (FT_F26Dot6)scaler->width,
57 (FT_F26Dot6)scaler->height,
78 } FTC_SizeNodeRec, *FTC_SizeNode;
80#define FTC_SIZE_NODE( x ) ( (FTC_SizeNode)( x ) )
83 FT_CALLBACK_DEF(
void )
84 ftc_size_node_done( FTC_MruNode ftcnode,
87 FTC_SizeNode node = (FTC_SizeNode)ftcnode;
91 FT_Done_Size( node->size );
95 FT_CALLBACK_DEF( FT_Bool )
96 ftc_size_node_compare( FTC_MruNode ftcnode,
97 FT_Pointer ftcscaler )
99 FTC_SizeNode node = (FTC_SizeNode)ftcnode;
100 FTC_Scaler scaler = (FTC_Scaler)ftcscaler;
101 FTC_Scaler scaler0 = &node->scaler;
104 if ( FTC_SCALER_COMPARE( scaler0, scaler ) )
106 FT_Activate_Size( node->size );
113 FT_CALLBACK_DEF( FT_Error )
114 ftc_size_node_init( FTC_MruNode ftcnode,
115 FT_Pointer ftcscaler,
116 FT_Pointer ftcmanager )
120 FTC_SizeNode node = (FTC_SizeNode)ftcnode;
121 FTC_Scaler scaler = (FTC_Scaler)ftcscaler;
122 FTC_Manager manager = (FTC_Manager)ftcmanager;
125 error = ftc_scaler_lookup_size( manager, scaler, &size );
129 node->scaler = scaler[0];
137 const FTC_MruListClassRec ftc_size_list_class =
139 sizeof ( FTC_SizeNodeRec ),
141 ftc_size_node_compare,
149 ftc_size_node_compare_faceid( FTC_MruNode ftcnode,
150 FT_Pointer ftcface_id )
152 FTC_SizeNode node = (FTC_SizeNode)ftcnode;
153 FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
156 return FT_BOOL( node->scaler.face_id == face_id );
162 FT_EXPORT_DEF( FT_Error )
163 FTC_Manager_LookupSize( FTC_Manager manager,
171 if ( !asize || !scaler )
172 return FT_THROW( Invalid_Argument );
177 return FT_THROW( Invalid_Cache_Handle );
181 FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_compare,
185 error = FTC_MruList_Lookup( &manager->sizes, scaler, &mrunode );
189 *asize = FTC_SIZE_NODE( mrunode )->size;
209 } FTC_FaceNodeRec, *FTC_FaceNode;
211#define FTC_FACE_NODE( x ) ( ( FTC_FaceNode )( x ) )
214 FT_CALLBACK_DEF( FT_Error )
215 ftc_face_node_init( FTC_MruNode ftcnode,
216 FT_Pointer ftcface_id,
217 FT_Pointer ftcmanager )
221 FTC_FaceNode node = (FTC_FaceNode)ftcnode;
222 FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
223 FTC_Manager manager = (FTC_Manager)ftcmanager;
226 error = manager->request_face( face_id,
228 manager->request_data,
234 FT_Done_Size( face->size );
237 node->face_id = face_id;
244 FT_CALLBACK_DEF(
void )
245 ftc_face_node_done( FTC_MruNode ftcnode,
246 FT_Pointer ftcmanager )
248 FTC_FaceNode node = (FTC_FaceNode)ftcnode;
249 FTC_Manager manager = (FTC_Manager)ftcmanager;
254 FTC_MruList_RemoveSelection( &manager->sizes,
255 ftc_size_node_compare_faceid,
259 FT_Done_Face( node->face );
261 node->face_id = NULL;
265 FT_CALLBACK_DEF( FT_Bool )
266 ftc_face_node_compare( FTC_MruNode ftcnode,
267 FT_Pointer ftcface_id )
269 FTC_FaceNode node = (FTC_FaceNode)ftcnode;
270 FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
273 return FT_BOOL( node->face_id == face_id );
278 const FTC_MruListClassRec ftc_face_list_class =
280 sizeof ( FTC_FaceNodeRec),
282 ftc_face_node_compare,
290 FT_EXPORT_DEF( FT_Error )
291 FTC_Manager_LookupFace( FTC_Manager manager,
300 return FT_THROW( Invalid_Argument );
305 return FT_THROW( Invalid_Cache_Handle );
310 FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_compare,
314 error = FTC_MruList_Lookup( &manager->faces, face_id, &mrunode );
318 *aface = FTC_FACE_NODE( mrunode )->face;
335 FT_EXPORT_DEF( FT_Error )
336 FTC_Manager_New( FT_Library library,
340 FTC_Face_Requester requester,
342 FTC_Manager *amanager )
346 FTC_Manager manager = NULL;
350 return FT_THROW( Invalid_Library_Handle );
352 if ( !amanager || !requester )
353 return FT_THROW( Invalid_Argument );
355 memory = library->memory;
357 if ( FT_QNEW( manager ) )
360 if ( max_faces == 0 )
361 max_faces = FTC_MAX_FACES_DEFAULT;
363 if ( max_sizes == 0 )
364 max_sizes = FTC_MAX_SIZES_DEFAULT;
366 if ( max_bytes == 0 )
367 max_bytes = FTC_MAX_BYTES_DEFAULT;
369 manager->library = library;
370 manager->memory = memory;
371 manager->max_weight = max_bytes;
372 manager->cur_weight = 0;
374 manager->request_face = requester;
375 manager->request_data = req_data;
377 FTC_MruList_Init( &manager->faces,
378 &ftc_face_list_class,
383 FTC_MruList_Init( &manager->sizes,
384 &ftc_size_list_class,
389 manager->nodes_list = NULL;
390 manager->num_nodes = 0;
391 manager->num_caches = 0;
402 FT_EXPORT_DEF(
void )
403 FTC_Manager_Done( FTC_Manager manager )
409 if ( !manager || !manager->library )
412 memory = manager->memory;
415 for ( idx = manager->num_caches; idx-- > 0; )
417 FTC_Cache cache = manager->caches[idx];
422 cache->clazz.cache_done( cache );
428 FTC_MruList_Done( &manager->sizes );
429 FTC_MruList_Done( &manager->faces );
437 FT_EXPORT_DEF(
void )
438 FTC_Manager_Reset( FTC_Manager manager )
443 FTC_MruList_Reset( &manager->sizes );
444 FTC_MruList_Reset( &manager->faces );
446 FTC_Manager_FlushN( manager, manager->num_nodes );
453 FTC_Manager_Check( FTC_Manager manager )
455 FTC_Node node, first;
458 first = manager->nodes_list;
463 FT_Offset weight = 0;
470 FTC_Cache cache = manager->caches[node->cache_index];
473 if ( node->cache_index >= manager->num_caches )
474 FT_TRACE0((
"FTC_Manager_Check: invalid node (cache index = %hu\n",
475 node->cache_index ));
477 weight += cache->clazz.node_weight( node, cache );
479 node = FTC_NODE_NEXT( node );
481 }
while ( node != first );
483 if ( weight != manager->cur_weight )
484 FT_TRACE0((
"FTC_Manager_Check: invalid weight %ld instead of %ld\n",
485 manager->cur_weight, weight ));
498 node = FTC_NODE_NEXT( node );
500 }
while ( node != first );
502 if ( count != manager->num_nodes )
503 FT_TRACE0((
"FTC_Manager_Check:"
504 " invalid cache node count %u instead of %u\n",
505 manager->num_nodes, count ));
519 FTC_Manager_Compress( FTC_Manager manager )
521 FTC_Node node, prev, first;
527 first = manager->nodes_list;
530 FTC_Manager_Check( manager );
532 FT_TRACE0((
"compressing, weight = %ld, max = %ld, nodes = %u\n",
533 manager->cur_weight, manager->max_weight,
534 manager->num_nodes ));
537 if ( manager->cur_weight < manager->max_weight || !first )
541 prev = FTC_NODE_PREV( first );
545 prev = FTC_NODE_PREV( node );
547 if ( node->ref_count <= 0 )
548 ftc_node_destroy( node, manager );
550 }
while ( node != first && manager->cur_weight > manager->max_weight );
556 FT_LOCAL_DEF( FT_Error )
557 FTC_Manager_RegisterCache( FTC_Manager manager,
558 FTC_CacheClass clazz,
561 FT_Error error = FT_ERR( Invalid_Argument );
562 FTC_Cache cache = NULL;
565 if ( manager && clazz && acache )
567 FT_Memory memory = manager->memory;
570 if ( manager->num_caches >= FTC_MAX_CACHES )
572 error = FT_THROW( Too_Many_Caches );
573 FT_ERROR((
"FTC_Manager_RegisterCache:"
574 " too many registered caches\n" ));
578 if ( !FT_QALLOC( cache, clazz->cache_size ) )
580 cache->manager = manager;
581 cache->memory = memory;
582 cache->clazz = clazz[0];
583 cache->org_class = clazz;
587 cache->index = manager->num_caches;
589 error = clazz->cache_init( cache );
592 clazz->cache_done( cache );
597 manager->caches[manager->num_caches++] = cache;
608 FT_LOCAL_DEF( FT_UInt )
609 FTC_Manager_FlushN( FTC_Manager manager,
612 FTC_Node first = manager->nodes_list;
618 if ( !first || !count )
622 prev = FTC_NODE_PREV( first );
626 prev = FTC_NODE_PREV( node );
629 if ( node->ref_count <= 0 )
631 ftc_node_destroy( node, manager );
634 }
while ( node != first && result < count );
642 FT_EXPORT_DEF(
void )
643 FTC_Manager_RemoveFaceID( FTC_Manager manager,
655 FTC_MruList_RemoveSelection( &manager->faces,
656 ftc_face_node_compare,
659 for ( nn = 0; nn < manager->num_caches; nn++ )
660 FTC_Cache_RemoveFaceID( manager->caches[nn], face_id );
666 FT_EXPORT_DEF(
void )
667 FTC_Node_Unref( FTC_Node node,
668 FTC_Manager manager )
672 node->cache_index < manager->num_caches )