Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 1 | /***************************************************************************/ |
| 2 | /* */ |
Werner Lemberg | d1b7475 | 2000-08-24 16:29:15 +0000 | [diff] [blame] | 3 | /* ftcmanag.c */ |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 4 | /* */ |
Werner Lemberg | d1b7475 | 2000-08-24 16:29:15 +0000 | [diff] [blame] | 5 | /* FreeType Cache Manager (body). */ |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 6 | /* */ |
| 7 | /* Copyright 2000 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 | |
Werner Lemberg | cc069be | 2000-12-08 16:17:16 +0000 | [diff] [blame^] | 18 | |
| 19 | #include <ft2build.h> |
| 20 | #include FT_CACHE_H |
| 21 | #include FT_CACHE_MANAGER_H |
| 22 | #include FT_INTERNAL_OBJECTS_H |
| 23 | #include FT_INTERNAL_DEBUG_H |
| 24 | #include FT_LIST_H |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 25 | |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 26 | |
| 27 | #undef FT_COMPONENT |
| 28 | #define FT_COMPONENT trace_cache |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 29 | |
David Turner | 3b2c50e | 2000-08-23 21:11:13 +0000 | [diff] [blame] | 30 | #define FTC_LRU_GET_MANAGER( lru ) (FTC_Manager)lru->user_data |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 31 | |
| 32 | |
Werner Lemberg | 4e9dae6 | 2000-08-29 16:50:01 +0000 | [diff] [blame] | 33 | /*************************************************************************/ |
| 34 | /*************************************************************************/ |
| 35 | /***** *****/ |
| 36 | /***** FACE & SIZE LRU CALLBACKS *****/ |
| 37 | /***** *****/ |
| 38 | /*************************************************************************/ |
| 39 | /*************************************************************************/ |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 40 | |
Werner Lemberg | 4e9dae6 | 2000-08-29 16:50:01 +0000 | [diff] [blame] | 41 | |
David Turner | 76a5f62 | 2000-11-04 01:55:49 +0000 | [diff] [blame] | 42 | FT_CALLBACK_DEF |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 43 | FT_Error ftc_manager_init_face( FT_Lru lru, |
| 44 | FT_LruNode node ) |
| 45 | { |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 46 | FTC_Manager manager = FTC_LRU_GET_MANAGER( lru ); |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 47 | FT_Error error; |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 48 | FT_Face face; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 49 | |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 50 | |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 51 | error = manager->request_face( (FTC_FaceID)node->key, |
David Turner | 3b2c50e | 2000-08-23 21:11:13 +0000 | [diff] [blame] | 52 | manager->library, |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 53 | manager->request_data, |
| 54 | (FT_Face*)&node->root.data ); |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 55 | if ( !error ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 56 | { |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 57 | /* destroy initial size object; it will be re-created later */ |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 58 | face = (FT_Face)node->root.data; |
Werner Lemberg | ab85523 | 2000-10-31 22:13:54 +0000 | [diff] [blame] | 59 | if ( face->size ) |
David Turner | ece6379 | 2000-10-28 23:34:45 +0000 | [diff] [blame] | 60 | FT_Done_Size( face->size ); |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 61 | } |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 62 | |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 63 | return error; |
| 64 | } |
| 65 | |
| 66 | |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 67 | /* helper function for ftc_manager_done_face() */ |
David Turner | 76a5f62 | 2000-11-04 01:55:49 +0000 | [diff] [blame] | 68 | FT_CALLBACK_DEF |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 69 | FT_Bool ftc_manager_size_selector( FT_Lru lru, |
| 70 | FT_LruNode node, |
| 71 | FT_Pointer data ) |
| 72 | { |
| 73 | FT_UNUSED( lru ); |
| 74 | |
| 75 | return ((FT_Size)node->root.data)->face == (FT_Face)data; |
| 76 | } |
| 77 | |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 78 | |
David Turner | 76a5f62 | 2000-11-04 01:55:49 +0000 | [diff] [blame] | 79 | FT_CALLBACK_DEF |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 80 | void ftc_manager_done_face( FT_Lru lru, |
| 81 | FT_LruNode node ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 82 | { |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 83 | FTC_Manager manager = FTC_LRU_GET_MANAGER( lru ); |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 84 | FT_Face face = (FT_Face)node->root.data; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 85 | |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 86 | |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 87 | /* we must begin by removing all sizes for the target face */ |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 88 | /* from the manager's list */ |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 89 | FT_Lru_Remove_Selection( manager->sizes_lru, |
| 90 | ftc_manager_size_selector, |
| 91 | face ); |
| 92 | |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 93 | /* all right, we can discard the face now */ |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 94 | FT_Done_Face( face ); |
| 95 | node->root.data = 0; |
| 96 | } |
| 97 | |
| 98 | |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 99 | typedef struct FTC_FontRequest_ |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 100 | { |
| 101 | FT_Face face; |
| 102 | FT_UShort width; |
| 103 | FT_UShort height; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 104 | |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 105 | } FTC_FontRequest; |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 106 | |
| 107 | |
David Turner | 76a5f62 | 2000-11-04 01:55:49 +0000 | [diff] [blame] | 108 | FT_CALLBACK_DEF |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 109 | FT_Error ftc_manager_init_size( FT_Lru lru, |
| 110 | FT_LruNode node ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 111 | { |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 112 | FTC_FontRequest* font_req = (FTC_FontRequest*)node->key; |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 113 | FT_Size size; |
| 114 | FT_Error error; |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 115 | FT_Face face = font_req->face; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 116 | |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 117 | FT_UNUSED( lru ); |
| 118 | |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 119 | |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 120 | node->root.data = 0; |
David Turner | 98d2701 | 2000-08-24 11:53:35 +0000 | [diff] [blame] | 121 | error = FT_New_Size( face, &size ); |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 122 | if ( !error ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 123 | { |
David Turner | 98d2701 | 2000-08-24 11:53:35 +0000 | [diff] [blame] | 124 | face->size = size; |
| 125 | error = FT_Set_Pixel_Sizes( face, |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 126 | font_req->width, |
| 127 | font_req->height ); |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 128 | if ( error ) |
| 129 | FT_Done_Size( size ); |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 130 | else |
| 131 | node->root.data = size; |
| 132 | } |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 133 | return error; |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 134 | } |
| 135 | |
| 136 | |
David Turner | 76a5f62 | 2000-11-04 01:55:49 +0000 | [diff] [blame] | 137 | FT_CALLBACK_DEF |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 138 | void ftc_manager_done_size( FT_Lru lru, |
| 139 | FT_LruNode node ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 140 | { |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 141 | FT_UNUSED( lru ); |
| 142 | |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 143 | FT_Done_Size( (FT_Size)node->root.data ); |
David Turner | 91bb165 | 2000-12-05 22:23:12 +0000 | [diff] [blame] | 144 | node->root.data = 0; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 145 | } |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 146 | |
| 147 | |
David Turner | 76a5f62 | 2000-11-04 01:55:49 +0000 | [diff] [blame] | 148 | FT_CALLBACK_DEF |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 149 | FT_Error ftc_manager_flush_size( FT_Lru lru, |
| 150 | FT_LruNode node, |
| 151 | FT_LruKey key ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 152 | { |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 153 | FTC_FontRequest* req = (FTC_FontRequest*)key; |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 154 | FT_Size size = (FT_Size)node->root.data; |
| 155 | FT_Error error; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 156 | |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 157 | |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 158 | if ( size->face == req->face ) |
| 159 | { |
| 160 | size->face->size = size; /* set current size */ |
| 161 | error = FT_Set_Pixel_Sizes( req->face, req->width, req->height ); |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 162 | if ( error ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 163 | FT_Done_Size( size ); |
| 164 | } |
| 165 | else |
| 166 | { |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 167 | FT_Done_Size( size ); |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 168 | node->key = key; |
| 169 | error = ftc_manager_init_size( lru, node ); |
| 170 | } |
| 171 | return error; |
| 172 | } |
| 173 | |
| 174 | |
David Turner | 76a5f62 | 2000-11-04 01:55:49 +0000 | [diff] [blame] | 175 | FT_CALLBACK_DEF |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 176 | FT_Bool ftc_manager_compare_size( FT_LruNode node, |
| 177 | FT_LruKey key ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 178 | { |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 179 | FTC_FontRequest* req = (FTC_FontRequest*)key; |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 180 | FT_Size size = (FT_Size)node->root.data; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 181 | |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 182 | FT_UNUSED( node ); |
| 183 | |
| 184 | |
| 185 | return ( size->face == req->face && |
| 186 | size->metrics.x_ppem == req->width && |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 187 | size->metrics.y_ppem == req->height ); |
| 188 | } |
| 189 | |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 190 | |
David Turner | 76a5f62 | 2000-11-04 01:55:49 +0000 | [diff] [blame] | 191 | FT_CALLBACK_TABLE_DEF |
| 192 | const FT_Lru_Class ftc_face_lru_class = |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 193 | { |
David Turner | 3b2c50e | 2000-08-23 21:11:13 +0000 | [diff] [blame] | 194 | sizeof ( FT_LruRec ), |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 195 | ftc_manager_init_face, |
| 196 | ftc_manager_done_face, |
| 197 | 0, |
| 198 | 0 |
| 199 | }; |
| 200 | |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 201 | |
David Turner | 76a5f62 | 2000-11-04 01:55:49 +0000 | [diff] [blame] | 202 | FT_CALLBACK_TABLE_DEF |
| 203 | const FT_Lru_Class ftc_size_lru_class = |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 204 | { |
David Turner | 3b2c50e | 2000-08-23 21:11:13 +0000 | [diff] [blame] | 205 | sizeof ( FT_LruRec ), |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 206 | ftc_manager_init_size, |
| 207 | ftc_manager_done_size, |
| 208 | ftc_manager_flush_size, |
| 209 | ftc_manager_compare_size |
| 210 | }; |
| 211 | |
| 212 | |
David Turner | 76a5f62 | 2000-11-04 01:55:49 +0000 | [diff] [blame] | 213 | FT_EXPORT_DEF( FT_Error ) FTC_Manager_New( FT_Library library, |
| 214 | FT_UInt max_faces, |
| 215 | FT_UInt max_sizes, |
| 216 | FT_ULong max_bytes, |
| 217 | FTC_Face_Requester requester, |
| 218 | FT_Pointer req_data, |
Werner Lemberg | 4b68007 | 2000-11-07 06:30:29 +0000 | [diff] [blame] | 219 | FTC_Manager *amanager ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 220 | { |
| 221 | FT_Error error; |
Werner Lemberg | d1b7475 | 2000-08-24 16:29:15 +0000 | [diff] [blame] | 222 | FT_Memory memory; |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 223 | FTC_Manager manager = 0; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 224 | |
| 225 | |
Werner Lemberg | d1b7475 | 2000-08-24 16:29:15 +0000 | [diff] [blame] | 226 | if ( !library ) |
| 227 | return FT_Err_Invalid_Library_Handle; |
| 228 | |
| 229 | memory = library->memory; |
| 230 | |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 231 | if ( ALLOC( manager, sizeof ( *manager ) ) ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 232 | goto Exit; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 233 | |
Werner Lemberg | d1b7475 | 2000-08-24 16:29:15 +0000 | [diff] [blame] | 234 | if ( max_faces == 0 ) |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 235 | max_faces = FTC_MAX_FACES_DEFAULT; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 236 | |
Werner Lemberg | d1b7475 | 2000-08-24 16:29:15 +0000 | [diff] [blame] | 237 | if ( max_sizes == 0 ) |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 238 | max_sizes = FTC_MAX_SIZES_DEFAULT; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 239 | |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 240 | if ( max_bytes == 0 ) |
| 241 | max_bytes = FTC_MAX_BYTES_DEFAULT; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 242 | |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 243 | error = FT_Lru_New( &ftc_face_lru_class, |
David Turner | 98d2701 | 2000-08-24 11:53:35 +0000 | [diff] [blame] | 244 | max_faces, |
David Turner | 3b2c50e | 2000-08-23 21:11:13 +0000 | [diff] [blame] | 245 | manager, |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 246 | memory, |
| 247 | 1, /* pre_alloc = TRUE */ |
| 248 | (FT_Lru*)&manager->faces_lru ); |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 249 | if ( error ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 250 | goto Exit; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 251 | |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 252 | error = FT_Lru_New( &ftc_size_lru_class, |
David Turner | 98d2701 | 2000-08-24 11:53:35 +0000 | [diff] [blame] | 253 | max_sizes, |
David Turner | 3b2c50e | 2000-08-23 21:11:13 +0000 | [diff] [blame] | 254 | manager, |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 255 | memory, |
| 256 | 1, /* pre_alloc = TRUE */ |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 257 | (FT_Lru*)&manager->sizes_lru ); |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 258 | if ( error ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 259 | goto Exit; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 260 | |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 261 | manager->library = library; |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 262 | manager->max_bytes = max_bytes; |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 263 | manager->request_face = requester; |
| 264 | manager->request_data = req_data; |
| 265 | *amanager = manager; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 266 | |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 267 | Exit: |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 268 | if ( error && manager ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 269 | { |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 270 | FT_Lru_Done( manager->faces_lru ); |
David Turner | 940d306 | 2000-12-05 23:07:16 +0000 | [diff] [blame] | 271 | FT_Lru_Done( manager->sizes_lru ); |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 272 | FREE( manager ); |
| 273 | } |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 274 | |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 275 | return error; |
| 276 | } |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 277 | |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 278 | |
Werner Lemberg | ada9503 | 2000-11-29 17:48:57 +0000 | [diff] [blame] | 279 | FT_EXPORT_DEF( void ) FTC_Manager_Done( FTC_Manager manager ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 280 | { |
Werner Lemberg | d1b7475 | 2000-08-24 16:29:15 +0000 | [diff] [blame] | 281 | FT_Memory memory; |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 282 | FT_UInt index; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 283 | |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 284 | |
Werner Lemberg | d1b7475 | 2000-08-24 16:29:15 +0000 | [diff] [blame] | 285 | if ( !manager || !manager->library ) |
| 286 | return; |
| 287 | |
| 288 | memory = manager->library->memory; |
| 289 | |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 290 | /* now discard all caches */ |
| 291 | for (index = 0; index < FTC_MAX_CACHES; index++ ) |
| 292 | { |
| 293 | FTC_Cache cache = manager->caches[index]; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 294 | |
| 295 | |
| 296 | if ( cache ) |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 297 | { |
| 298 | cache->clazz->done_cache( cache ); |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 299 | FREE( cache ); |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 300 | manager->caches[index] = 0; |
| 301 | } |
| 302 | } |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 303 | |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 304 | /* discard faces and sizes */ |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 305 | FT_Lru_Done( manager->faces_lru ); |
David Turner | 91bb165 | 2000-12-05 22:23:12 +0000 | [diff] [blame] | 306 | manager->faces_lru = 0; |
| 307 | |
| 308 | FT_Lru_Done( manager->sizes_lru ); |
David Turner | 940d306 | 2000-12-05 23:07:16 +0000 | [diff] [blame] | 309 | manager->sizes_lru = 0; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 310 | |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 311 | FREE( manager ); |
| 312 | } |
| 313 | |
| 314 | |
Werner Lemberg | ada9503 | 2000-11-29 17:48:57 +0000 | [diff] [blame] | 315 | FT_EXPORT_DEF( void ) FTC_Manager_Reset( FTC_Manager manager ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 316 | { |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 317 | if (manager ) |
| 318 | { |
| 319 | FT_Lru_Reset( manager->sizes_lru ); |
| 320 | FT_Lru_Reset( manager->faces_lru ); |
| 321 | } |
Werner Lemberg | ab85523 | 2000-10-31 22:13:54 +0000 | [diff] [blame] | 322 | /* XXX: FIXME: flush the caches? */ |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 323 | } |
| 324 | |
| 325 | |
Werner Lemberg | ada9503 | 2000-11-29 17:48:57 +0000 | [diff] [blame] | 326 | FT_EXPORT_DEF( FT_Error ) FTC_Manager_Lookup_Face( FTC_Manager manager, |
| 327 | FTC_FaceID face_id, |
| 328 | FT_Face *aface ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 329 | { |
Werner Lemberg | d1b7475 | 2000-08-24 16:29:15 +0000 | [diff] [blame] | 330 | if ( !manager ) |
Werner Lemberg | 95853c8 | 2000-08-26 22:16:44 +0000 | [diff] [blame] | 331 | return FT_Err_Invalid_Cache_Handle; |
Werner Lemberg | d1b7475 | 2000-08-24 16:29:15 +0000 | [diff] [blame] | 332 | |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 333 | return FT_Lru_Lookup( manager->faces_lru, |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 334 | (FT_LruKey)face_id, |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 335 | (FT_Pointer*)aface ); |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 336 | } |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 337 | |
| 338 | |
Werner Lemberg | ada9503 | 2000-11-29 17:48:57 +0000 | [diff] [blame] | 339 | FT_EXPORT_DEF( FT_Error ) FTC_Manager_Lookup_Size( FTC_Manager manager, |
| 340 | FTC_Font font, |
| 341 | FT_Face *aface, |
| 342 | FT_Size *asize ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 343 | { |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 344 | FTC_FontRequest req; |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 345 | FT_Error error; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 346 | |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 347 | |
Werner Lemberg | d1b7475 | 2000-08-24 16:29:15 +0000 | [diff] [blame] | 348 | /* check for valid `manager' delayed to FTC_Manager_Lookup_Face() */ |
| 349 | |
| 350 | if ( aface ) |
David Turner | 3b2c50e | 2000-08-23 21:11:13 +0000 | [diff] [blame] | 351 | *aface = 0; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 352 | |
Werner Lemberg | d1b7475 | 2000-08-24 16:29:15 +0000 | [diff] [blame] | 353 | if ( asize ) |
David Turner | 3b2c50e | 2000-08-23 21:11:13 +0000 | [diff] [blame] | 354 | *asize = 0; |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 355 | |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 356 | error = FTC_Manager_Lookup_Face( manager, font->face_id, aface ); |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 357 | if ( !error ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 358 | { |
David Turner | 3b2c50e | 2000-08-23 21:11:13 +0000 | [diff] [blame] | 359 | FT_Size size; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 360 | |
Werner Lemberg | d1b7475 | 2000-08-24 16:29:15 +0000 | [diff] [blame] | 361 | |
David Turner | f88969a | 2000-10-12 00:28:00 +0000 | [diff] [blame] | 362 | req.face = *aface; |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 363 | req.width = font->pix_width; |
| 364 | req.height = font->pix_height; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 365 | |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 366 | error = FT_Lru_Lookup( manager->sizes_lru, |
| 367 | (FT_LruKey)&req, |
David Turner | 3b2c50e | 2000-08-23 21:11:13 +0000 | [diff] [blame] | 368 | (FT_Pointer*)&size ); |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 369 | if ( !error ) |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 370 | { |
| 371 | /* select the size as the current one for this face */ |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 372 | (*aface)->size = size; |
| 373 | |
Werner Lemberg | d1b7475 | 2000-08-24 16:29:15 +0000 | [diff] [blame] | 374 | if ( asize ) |
David Turner | 3b2c50e | 2000-08-23 21:11:13 +0000 | [diff] [blame] | 375 | *asize = size; |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 376 | } |
| 377 | } |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 378 | |
David Turner | b466a76 | 2000-08-23 11:22:30 +0000 | [diff] [blame] | 379 | return error; |
| 380 | } |
| 381 | |
| 382 | |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 383 | /* `Compress' the manager's data, i.e., get rid of old cache nodes */ |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 384 | /* that are not referenced anymore in order to limit the total */ |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 385 | /* memory used by the cache. */ |
David Turner | 76a5f62 | 2000-11-04 01:55:49 +0000 | [diff] [blame] | 386 | FT_EXPORT_DEF( void ) FTC_Manager_Compress( FTC_Manager manager ) |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 387 | { |
| 388 | FT_ListNode node; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 389 | |
| 390 | |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 391 | node = manager->global_lru.tail; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 392 | while ( manager->num_bytes > manager->max_bytes && node ) |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 393 | { |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 394 | FTC_CacheNode cache_node = FTC_LIST_TO_CACHENODE( node ); |
| 395 | FTC_CacheNode_Data* data = FTC_CACHENODE_TO_DATA_P( cache_node ); |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 396 | FTC_Cache cache; |
| 397 | FT_ListNode prev = node->prev; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 398 | |
| 399 | |
| 400 | if ( data->ref_count <= 0 ) |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 401 | { |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 402 | /* ok, we are going to remove this node */ |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 403 | FT_List_Remove( &manager->global_lru, node ); |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 404 | |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 405 | /* finalize cache node */ |
| 406 | cache = manager->caches[data->cache_index]; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 407 | if ( cache ) |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 408 | { |
| 409 | FTC_CacheNode_Class* clazz = cache->node_clazz; |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 410 | |
| 411 | |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 412 | manager->num_bytes -= clazz->size_node( cache_node, |
David Turner | ece6379 | 2000-10-28 23:34:45 +0000 | [diff] [blame] | 413 | cache->cache_data ); |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 414 | |
David Turner | ece6379 | 2000-10-28 23:34:45 +0000 | [diff] [blame] | 415 | clazz->destroy_node( cache_node, cache->cache_data ); |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 416 | } |
| 417 | else |
| 418 | { |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 419 | /* this should never happen! */ |
| 420 | FT_ERROR(( "FTC_Manager_Compress: Cache Manager is corrupted!\n" )); |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 421 | } |
Werner Lemberg | e4b32a5 | 2000-10-31 20:42:18 +0000 | [diff] [blame] | 422 | |
David Turner | ece6379 | 2000-10-28 23:34:45 +0000 | [diff] [blame] | 423 | /* check, just in case of general corruption :-) */ |
Werner Lemberg | ab85523 | 2000-10-31 22:13:54 +0000 | [diff] [blame] | 424 | if ( manager->num_nodes <= 0 ) |
| 425 | FT_ERROR(( "FTC_Manager_Compress: Invalid cache node count!\n" )); |
David Turner | ece6379 | 2000-10-28 23:34:45 +0000 | [diff] [blame] | 426 | else |
| 427 | manager->num_nodes--; |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 428 | } |
| 429 | node = prev; |
| 430 | } |
| 431 | } |
| 432 | |
| 433 | |
Werner Lemberg | ada9503 | 2000-11-29 17:48:57 +0000 | [diff] [blame] | 434 | FT_EXPORT_DEF( FT_Error ) FTC_Manager_Register_Cache( |
| 435 | FTC_Manager manager, |
| 436 | FTC_Cache_Class* clazz, |
| 437 | FTC_Cache *acache ) |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 438 | { |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 439 | FT_Error error = FT_Err_Invalid_Argument; |
| 440 | |
| 441 | |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 442 | if ( manager && clazz && acache ) |
| 443 | { |
| 444 | FT_Memory memory = manager->library->memory; |
| 445 | FTC_Cache cache; |
| 446 | FT_UInt index = 0; |
| 447 | |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 448 | |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 449 | /* by default, return 0 */ |
| 450 | *acache = 0; |
| 451 | |
| 452 | /* check for an empty cache slot in the manager's table */ |
| 453 | for ( index = 0; index < FTC_MAX_CACHES; index++ ) |
| 454 | { |
| 455 | if ( manager->caches[index] == 0 ) |
| 456 | break; |
| 457 | } |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 458 | |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 459 | /* return an error if there are too many registered caches */ |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 460 | if ( index >= FTC_MAX_CACHES ) |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 461 | { |
| 462 | error = FT_Err_Too_Many_Caches; |
| 463 | FT_ERROR(( "FTC_Manager_Register_Cache:" )); |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 464 | FT_ERROR(( " too many registered caches\n" )); |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 465 | goto Exit; |
| 466 | } |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 467 | |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 468 | if ( !ALLOC( cache, clazz->cache_byte_size ) ) |
| 469 | { |
| 470 | cache->manager = manager; |
| 471 | cache->memory = memory; |
| 472 | cache->clazz = clazz; |
Werner Lemberg | e4b32a5 | 2000-10-31 20:42:18 +0000 | [diff] [blame] | 473 | |
Werner Lemberg | ab85523 | 2000-10-31 22:13:54 +0000 | [diff] [blame] | 474 | /* THIS IS VERY IMPORTANT! IT WILL WRETCH THE MANAGER */ |
| 475 | /* IF IT IS NOT SET CORRECTLY */ |
David Turner | 2909475 | 2000-10-31 10:58:23 +0000 | [diff] [blame] | 476 | cache->cache_index = index; |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 477 | |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 478 | if ( clazz->init_cache ) |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 479 | error = clazz->init_cache( cache ); |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 480 | |
| 481 | if ( error ) |
| 482 | FREE( cache ); |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 483 | else |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 484 | manager->caches[index] = *acache = cache; |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 485 | } |
| 486 | } |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 487 | |
David Turner | ebdce83 | 2000-09-19 01:11:11 +0000 | [diff] [blame] | 488 | Exit: |
| 489 | return error; |
| 490 | } |
| 491 | |
Werner Lemberg | eddd990 | 2000-10-12 05:05:40 +0000 | [diff] [blame] | 492 | |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 493 | /* END */ |