mgh: fix for default HDD DMA mode, that wasn't correctly set
[open-ps2-loader.git] / thirdparty / freetype-2.3.12 / src / cache / ftcmanag.c
blobf2a298e7d906b6918ed718945e762a47f65c55e6
1 /***************************************************************************/
2 /* */
3 /* ftcmanag.c */
4 /* */
5 /* FreeType Cache Manager (body). */
6 /* */
7 /* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2008, 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 /***************************************************************************/
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
26 #include "ftccback.h"
27 #include "ftcerror.h"
29 #ifdef FT_CONFIG_OPTION_PIC
30 #error "cache system does not support PIC yet"
31 #endif
34 #undef FT_COMPONENT
35 #define FT_COMPONENT trace_cache
37 #define FTC_LRU_GET_MANAGER( lru ) ( (FTC_Manager)(lru)->user_data )
40 static FT_Error
41 ftc_scaler_lookup_size( FTC_Manager manager,
42 FTC_Scaler scaler,
43 FT_Size *asize )
45 FT_Face face;
46 FT_Size size = NULL;
47 FT_Error error;
50 error = FTC_Manager_LookupFace( manager, scaler->face_id, &face );
51 if ( error )
52 goto Exit;
54 error = FT_New_Size( face, &size );
55 if ( error )
56 goto Exit;
58 FT_Activate_Size( size );
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 )
67 FT_Done_Size( size );
68 size = NULL;
71 Exit:
72 *asize = size;
73 return error;
77 typedef struct FTC_SizeNodeRec_
79 FTC_MruNodeRec node;
80 FT_Size size;
81 FTC_ScalerRec scaler;
83 } FTC_SizeNodeRec, *FTC_SizeNode;
85 #define FTC_SIZE_NODE( x ) ( (FTC_SizeNode)( x ) )
88 FT_CALLBACK_DEF( void )
89 ftc_size_node_done( FTC_MruNode ftcnode,
90 FT_Pointer data )
92 FTC_SizeNode node = (FTC_SizeNode)ftcnode;
93 FT_Size size = node->size;
94 FT_UNUSED( data );
97 if ( size )
98 FT_Done_Size( size );
102 FT_CALLBACK_DEF( FT_Bool )
103 ftc_size_node_compare( FTC_MruNode ftcnode,
104 FT_Pointer ftcscaler )
106 FTC_SizeNode node = (FTC_SizeNode)ftcnode;
107 FTC_Scaler scaler = (FTC_Scaler)ftcscaler;
108 FTC_Scaler scaler0 = &node->scaler;
111 if ( FTC_SCALER_COMPARE( scaler0, scaler ) )
113 FT_Activate_Size( node->size );
114 return 1;
116 return 0;
120 FT_CALLBACK_DEF( FT_Error )
121 ftc_size_node_init( FTC_MruNode ftcnode,
122 FT_Pointer ftcscaler,
123 FT_Pointer ftcmanager )
125 FTC_SizeNode node = (FTC_SizeNode)ftcnode;
126 FTC_Scaler scaler = (FTC_Scaler)ftcscaler;
127 FTC_Manager manager = (FTC_Manager)ftcmanager;
130 node->scaler = scaler[0];
132 return ftc_scaler_lookup_size( manager, scaler, &node->size );
136 FT_CALLBACK_DEF( FT_Error )
137 ftc_size_node_reset( FTC_MruNode ftcnode,
138 FT_Pointer ftcscaler,
139 FT_Pointer ftcmanager )
141 FTC_SizeNode node = (FTC_SizeNode)ftcnode;
142 FTC_Scaler scaler = (FTC_Scaler)ftcscaler;
143 FTC_Manager manager = (FTC_Manager)ftcmanager;
146 FT_Done_Size( node->size );
148 node->scaler = scaler[0];
150 return ftc_scaler_lookup_size( manager, scaler, &node->size );
154 FT_CALLBACK_TABLE_DEF
155 const FTC_MruListClassRec ftc_size_list_class =
157 sizeof ( FTC_SizeNodeRec ),
158 ftc_size_node_compare,
159 ftc_size_node_init,
160 ftc_size_node_reset,
161 ftc_size_node_done
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 )
170 FTC_SizeNode node = (FTC_SizeNode)ftcnode;
171 FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
174 return FT_BOOL( node->scaler.face_id == face_id );
178 /* documentation is in ftcache.h */
180 FT_EXPORT_DEF( FT_Error )
181 FTC_Manager_LookupSize( FTC_Manager manager,
182 FTC_Scaler scaler,
183 FT_Size *asize )
185 FT_Error error;
186 FTC_MruNode mrunode;
189 if ( asize == NULL )
190 return FTC_Err_Invalid_Argument;
192 *asize = NULL;
194 if ( !manager )
195 return FTC_Err_Invalid_Cache_Handle;
197 #ifdef FTC_INLINE
199 FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_compare,
200 mrunode, error );
202 #else
203 error = FTC_MruList_Lookup( &manager->sizes, scaler, &mrunode );
204 #endif
206 if ( !error )
207 *asize = FTC_SIZE_NODE( mrunode )->size;
209 return error;
213 /*************************************************************************/
214 /*************************************************************************/
215 /***** *****/
216 /***** FACE MRU IMPLEMENTATION *****/
217 /***** *****/
218 /*************************************************************************/
219 /*************************************************************************/
221 typedef struct FTC_FaceNodeRec_
223 FTC_MruNodeRec node;
224 FTC_FaceID face_id;
225 FT_Face face;
227 } FTC_FaceNodeRec, *FTC_FaceNode;
229 #define FTC_FACE_NODE( x ) ( ( FTC_FaceNode )( x ) )
232 FT_CALLBACK_DEF( FT_Error )
233 ftc_face_node_init( FTC_MruNode ftcnode,
234 FT_Pointer ftcface_id,
235 FT_Pointer ftcmanager )
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;
243 node->face_id = face_id;
245 error = manager->request_face( face_id,
246 manager->library,
247 manager->request_data,
248 &node->face );
249 if ( !error )
251 /* destroy initial size object; it will be re-created later */
252 if ( node->face->size )
253 FT_Done_Size( node->face->size );
256 return error;
260 FT_CALLBACK_DEF( void )
261 ftc_face_node_done( FTC_MruNode ftcnode,
262 FT_Pointer ftcmanager )
264 FTC_FaceNode node = (FTC_FaceNode)ftcnode;
265 FTC_Manager manager = (FTC_Manager)ftcmanager;
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 );
274 /* all right, we can discard the face now */
275 FT_Done_Face( node->face );
276 node->face = NULL;
277 node->face_id = NULL;
281 FT_CALLBACK_DEF( FT_Bool )
282 ftc_face_node_compare( FTC_MruNode ftcnode,
283 FT_Pointer ftcface_id )
285 FTC_FaceNode node = (FTC_FaceNode)ftcnode;
286 FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
289 return FT_BOOL( node->face_id == face_id );
293 FT_CALLBACK_TABLE_DEF
294 const FTC_MruListClassRec ftc_face_list_class =
296 sizeof ( FTC_FaceNodeRec),
298 ftc_face_node_compare,
299 ftc_face_node_init,
300 0, /* FTC_MruNode_ResetFunc */
301 ftc_face_node_done
305 /* documentation is in ftcache.h */
307 FT_EXPORT_DEF( FT_Error )
308 FTC_Manager_LookupFace( FTC_Manager manager,
309 FTC_FaceID face_id,
310 FT_Face *aface )
312 FT_Error error;
313 FTC_MruNode mrunode;
316 if ( aface == NULL )
317 return FTC_Err_Invalid_Argument;
319 *aface = NULL;
321 if ( !manager )
322 return FTC_Err_Invalid_Cache_Handle;
324 /* we break encapsulation for the sake of speed */
325 #ifdef FTC_INLINE
327 FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_compare,
328 mrunode, error );
330 #else
331 error = FTC_MruList_Lookup( &manager->faces, face_id, &mrunode );
332 #endif
334 if ( !error )
335 *aface = FTC_FACE_NODE( mrunode )->face;
337 return error;
341 /*************************************************************************/
342 /*************************************************************************/
343 /***** *****/
344 /***** CACHE MANAGER ROUTINES *****/
345 /***** *****/
346 /*************************************************************************/
347 /*************************************************************************/
350 /* documentation is in ftcache.h */
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 )
361 FT_Error error;
362 FT_Memory memory;
363 FTC_Manager manager = 0;
366 if ( !library )
367 return FTC_Err_Invalid_Library_Handle;
369 memory = library->memory;
371 if ( FT_NEW( manager ) )
372 goto Exit;
374 if ( max_faces == 0 )
375 max_faces = FTC_MAX_FACES_DEFAULT;
377 if ( max_sizes == 0 )
378 max_sizes = FTC_MAX_SIZES_DEFAULT;
380 if ( max_bytes == 0 )
381 max_bytes = FTC_MAX_BYTES_DEFAULT;
383 manager->library = library;
384 manager->memory = memory;
385 manager->max_weight = max_bytes;
387 manager->request_face = requester;
388 manager->request_data = req_data;
390 FTC_MruList_Init( &manager->faces,
391 &ftc_face_list_class,
392 max_faces,
393 manager,
394 memory );
396 FTC_MruList_Init( &manager->sizes,
397 &ftc_size_list_class,
398 max_sizes,
399 manager,
400 memory );
402 *amanager = manager;
404 Exit:
405 return error;
409 /* documentation is in ftcache.h */
411 FT_EXPORT_DEF( void )
412 FTC_Manager_Done( FTC_Manager manager )
414 FT_Memory memory;
415 FT_UInt idx;
418 if ( !manager || !manager->library )
419 return;
421 memory = manager->memory;
423 /* now discard all caches */
424 for (idx = manager->num_caches; idx-- > 0; )
426 FTC_Cache cache = manager->caches[idx];
429 if ( cache )
431 cache->clazz.cache_done( cache );
432 FT_FREE( cache );
433 manager->caches[idx] = NULL;
436 manager->num_caches = 0;
438 /* discard faces and sizes */
439 FTC_MruList_Done( &manager->sizes );
440 FTC_MruList_Done( &manager->faces );
442 manager->library = NULL;
443 manager->memory = NULL;
445 FT_FREE( manager );
449 /* documentation is in ftcache.h */
451 FT_EXPORT_DEF( void )
452 FTC_Manager_Reset( FTC_Manager manager )
454 if ( manager )
456 FTC_MruList_Reset( &manager->sizes );
457 FTC_MruList_Reset( &manager->faces );
459 /* XXX: FIXME: flush the caches? */
463 #ifdef FT_DEBUG_ERROR
465 static void
466 FTC_Manager_Check( FTC_Manager manager )
468 FTC_Node node, first;
471 first = manager->nodes_list;
473 /* check node weights */
474 if ( first )
476 FT_ULong weight = 0;
479 node = first;
483 FTC_Cache cache = manager->caches[node->cache_index];
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 );
492 node = FTC_NODE__NEXT( node );
494 } while ( node != first );
496 if ( weight != manager->cur_weight )
497 FT_TRACE0(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n",
498 manager->cur_weight, weight ));
501 /* check circular list */
502 if ( first )
504 FT_UFast count = 0;
507 node = first;
510 count++;
511 node = FTC_NODE__NEXT( node );
513 } while ( node != first );
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 ));
522 #endif /* FT_DEBUG_ERROR */
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. */
529 /* documentation is in ftcmanag.h */
531 FT_LOCAL_DEF( void )
532 FTC_Manager_Compress( FTC_Manager manager )
534 FTC_Node node, first;
537 if ( !manager )
538 return;
540 first = manager->nodes_list;
542 #ifdef FT_DEBUG_ERROR
543 FTC_Manager_Check( manager );
545 FT_TRACE0(( "compressing, weight = %ld, max = %ld, nodes = %d\n",
546 manager->cur_weight, manager->max_weight,
547 manager->num_nodes ));
548 #endif
550 if ( manager->cur_weight < manager->max_weight || first == NULL )
551 return;
553 /* go to last node -- it's a circular list */
554 node = FTC_NODE__PREV( first );
557 FTC_Node prev;
560 prev = ( node == first ) ? NULL : FTC_NODE__PREV( node );
562 if ( node->ref_count <= 0 )
563 ftc_node_destroy( node, manager );
565 node = prev;
567 } while ( node && manager->cur_weight > manager->max_weight );
571 /* documentation is in ftcmanag.h */
573 FT_LOCAL_DEF( FT_Error )
574 FTC_Manager_RegisterCache( FTC_Manager manager,
575 FTC_CacheClass clazz,
576 FTC_Cache *acache )
578 FT_Error error = FTC_Err_Invalid_Argument;
579 FTC_Cache cache = NULL;
582 if ( manager && clazz && acache )
584 FT_Memory memory = manager->memory;
587 if ( manager->num_caches >= FTC_MAX_CACHES )
589 error = FTC_Err_Too_Many_Caches;
590 FT_ERROR(( "FTC_Manager_RegisterCache:"
591 " too many registered caches\n" ));
592 goto Exit;
595 if ( !FT_ALLOC( cache, clazz->cache_size ) )
597 cache->manager = manager;
598 cache->memory = memory;
599 cache->clazz = clazz[0];
600 cache->org_class = clazz;
602 /* THIS IS VERY IMPORTANT! IT WILL WRETCH THE MANAGER */
603 /* IF IT IS NOT SET CORRECTLY */
604 cache->index = manager->num_caches;
606 error = clazz->cache_init( cache );
607 if ( error )
609 clazz->cache_done( cache );
610 FT_FREE( cache );
611 goto Exit;
614 manager->caches[manager->num_caches++] = cache;
618 Exit:
619 if ( acache )
620 *acache = cache;
621 return error;
625 FT_LOCAL_DEF( FT_UInt )
626 FTC_Manager_FlushN( FTC_Manager manager,
627 FT_UInt count )
629 FTC_Node first = manager->nodes_list;
630 FTC_Node node;
631 FT_UInt result;
634 /* try to remove `count' nodes from the list */
635 if ( first == NULL ) /* empty list! */
636 return 0;
638 /* go to last node - it's a circular list */
639 node = FTC_NODE__PREV(first);
640 for ( result = 0; result < count; )
642 FTC_Node prev = FTC_NODE__PREV( node );
645 /* don't touch locked nodes */
646 if ( node->ref_count <= 0 )
648 ftc_node_destroy( node, manager );
649 result++;
652 if ( node == first )
653 break;
655 node = prev;
657 return result;
661 /* documentation is in ftcache.h */
663 FT_EXPORT_DEF( void )
664 FTC_Manager_RemoveFaceID( FTC_Manager manager,
665 FTC_FaceID face_id )
667 FT_UInt nn;
669 /* this will remove all FTC_SizeNode that correspond to
670 * the face_id as well
672 FTC_MruList_RemoveSelection( &manager->faces,
673 (FTC_MruNode_CompareFunc)NULL,
674 face_id );
676 for ( nn = 0; nn < manager->num_caches; nn++ )
677 FTC_Cache_RemoveFaceID( manager->caches[nn], face_id );
681 /* documentation is in ftcache.h */
683 FT_EXPORT_DEF( void )
684 FTC_Node_Unref( FTC_Node node,
685 FTC_Manager manager )
687 if ( node && (FT_UInt)node->cache_index < manager->num_caches )
688 node->ref_count--;
692 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
694 FT_EXPORT_DEF( FT_Error )
695 FTC_Manager_Lookup_Face( FTC_Manager manager,
696 FTC_FaceID face_id,
697 FT_Face *aface )
699 return FTC_Manager_LookupFace( manager, face_id, aface );
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 )
709 FTC_ScalerRec scaler;
710 FT_Error error;
711 FT_Size size;
712 FT_Face face;
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;
722 error = FTC_Manager_LookupSize( manager, &scaler, &size );
723 if ( error )
725 face = NULL;
726 size = NULL;
728 else
729 face = size->face;
731 if ( aface )
732 *aface = face;
734 if ( asize )
735 *asize = size;
737 return error;
740 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
743 /* END */