OLD | NEW |
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* */ | 2 /* */ |
3 /* ftutil.c */ | 3 /* ftutil.c */ |
4 /* */ | 4 /* */ |
5 /* FreeType utility file for memory and list management (body). */ | 5 /* FreeType utility file for memory and list management (body). */ |
6 /* */ | 6 /* */ |
7 /* Copyright 2002, 2004-2007, 2013 by */ | 7 /* Copyright 2002, 2004-2007, 2013 by */ |
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ | 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
9 /* */ | 9 /* */ |
10 /* This file is part of the FreeType project, and may only be used, */ | 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 */ | 11 /* modified, and distributed under the terms of the FreeType project */ |
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
13 /* this file you indicate that you have read the license and */ | 13 /* this file you indicate that you have read the license and */ |
14 /* understand and accept it fully. */ | 14 /* understand and accept it fully. */ |
15 /* */ | 15 /* */ |
16 /***************************************************************************/ | 16 /***************************************************************************/ |
17 | 17 |
18 | 18 |
19 #include "../../include/ft2build.h" | 19 #include <ft2build.h> |
20 #include "../../include/freetype/internal/ftdebug.h" | 20 #include FT_INTERNAL_DEBUG_H |
21 #include "../../include/freetype/internal/ftmemory.h" | 21 #include FT_INTERNAL_MEMORY_H |
22 #include "../../include/freetype/internal/ftobjs.h" | 22 #include FT_INTERNAL_OBJECTS_H |
23 #include "../../include/freetype/ftlist.h" | 23 #include FT_LIST_H |
24 | 24 |
25 | 25 |
26 /*************************************************************************/ | 26 /*************************************************************************/ |
27 /* */ | 27 /* */ |
28 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ | 28 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
29 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ | 29 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
30 /* messages during execution. */ | 30 /* messages during execution. */ |
31 /* */ | 31 /* */ |
32 #undef FT_COMPONENT | 32 #undef FT_COMPONENT |
33 #define FT_COMPONENT trace_memory | 33 #define FT_COMPONENT trace_memory |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 if ( block2 == NULL ) | 156 if ( block2 == NULL ) |
157 error = FT_THROW( Out_Of_Memory ); | 157 error = FT_THROW( Out_Of_Memory ); |
158 else | 158 else |
159 block = block2; | 159 block = block2; |
160 } | 160 } |
161 | 161 |
162 *p_error = error; | 162 *p_error = error; |
163 return block; | 163 return block; |
164 } | 164 } |
165 | 165 |
166 #ifdef _XYQ_MEM_DEBUG /** XYQ 2006-10-12 */ | |
167 FT_BASE_DEF( FT_Pointer ) | |
168 ft_mem_allocdebug( FT_Memory memory, | |
169 FT_Long size, const char* file, int line, | |
170 FT_Error *p_error ) | |
171 { | |
172 FT_Error error; | |
173 FT_Pointer block = ft_mem_qallocdebug( memory, size, file, line, &error ); | |
174 | |
175 if ( !error && size > 0 ) | |
176 FT_MEM_ZERO( block, size ); | |
177 | |
178 *p_error = error; | |
179 return block; | |
180 } | |
181 | |
182 | 166 |
183 FT_BASE_DEF( FT_Pointer ) | |
184 ft_mem_qallocdebug( FT_Memory memory, | |
185 FT_Long size, const char* file, int line, | |
186 FT_Error *p_error ) | |
187 { | |
188 FT_Error error = FT_Err_Ok; | |
189 FT_Pointer block = NULL; | |
190 | |
191 | |
192 if ( size > 0 ) | |
193 { | |
194 block = memory->allocdebug( memory, size, file, line ); | |
195 if ( block == NULL ) | |
196 error = FT_Err_Out_Of_Memory; | |
197 } | |
198 else if ( size < 0 ) | |
199 { | |
200 /* may help catch/prevent security issues */ | |
201 error = FT_Err_Invalid_Argument; | |
202 } | |
203 | |
204 *p_error = error; | |
205 return block; | |
206 } | |
207 | |
208 | |
209 FT_BASE_DEF( FT_Pointer ) | |
210 ft_mem_reallocdebug( FT_Memory memory, | |
211 FT_Long item_size, | |
212 FT_Long cur_count, | |
213 FT_Long new_count, | |
214 void* block, const char* file, int line, | |
215 FT_Error *p_error ) | |
216 { | |
217 FT_Error error = FT_Err_Ok; | |
218 | |
219 block = ft_mem_qreallocdebug( memory, item_size, | |
220 cur_count, new_count, block, file, line, &error ); | |
221 if ( !error && new_count > cur_count ) | |
222 FT_MEM_ZERO( (char*)block + cur_count * item_size, | |
223 ( new_count - cur_count ) * item_size ); | |
224 | |
225 *p_error = error; | |
226 return block; | |
227 } | |
228 | |
229 | |
230 FT_BASE_DEF( FT_Pointer ) | |
231 ft_mem_qreallocdebug( FT_Memory memory, | |
232 FT_Long item_size, | |
233 FT_Long cur_count, | |
234 FT_Long new_count, | |
235 void* block, const char* file, int line, | |
236 FT_Error *p_error ) | |
237 { | |
238 FT_Error error = FT_Err_Ok; | |
239 | |
240 | |
241 if ( cur_count < 0 || new_count < 0 || item_size <= 0 ) | |
242 { | |
243 /* may help catch/prevent nasty security issues */ | |
244 error = FT_Err_Invalid_Argument; | |
245 } | |
246 else if ( new_count == 0 ) | |
247 { | |
248 ft_mem_free( memory, block ); | |
249 block = NULL; | |
250 } | |
251 else if ( new_count > FT_INT_MAX/item_size ) | |
252 { | |
253 error = FT_Err_Array_Too_Large; | |
254 } | |
255 else if ( cur_count == 0 ) | |
256 { | |
257 FT_ASSERT( block == NULL ); | |
258 | |
259 block = ft_mem_allocdebug( memory, new_count*item_size, file, line, &error
); | |
260 } | |
261 else | |
262 { | |
263 FT_Pointer block2; | |
264 FT_Long cur_size = cur_count*item_size; | |
265 FT_Long new_size = new_count*item_size; | |
266 | |
267 | |
268 block2 = memory->realloc( memory, cur_size, new_size, block ); | |
269 if ( block2 == NULL ) | |
270 error = FT_Err_Out_Of_Memory; | |
271 else | |
272 block = block2; | |
273 } | |
274 | |
275 *p_error = error; | |
276 return block; | |
277 } | |
278 #endif | |
279 FT_BASE_DEF( void ) | 167 FT_BASE_DEF( void ) |
280 ft_mem_free( FT_Memory memory, | 168 ft_mem_free( FT_Memory memory, |
281 const void *P ) | 169 const void *P ) |
282 { | 170 { |
283 if ( P ) | 171 if ( P ) |
284 memory->free( memory, (void*)P ); | 172 memory->free( memory, (void*)P ); |
285 } | 173 } |
286 | 174 |
287 | 175 |
288 FT_BASE_DEF( FT_Pointer ) | 176 FT_BASE_DEF( FT_Pointer ) |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 | 238 |
351 /* documentation is in ftlist.h */ | 239 /* documentation is in ftlist.h */ |
352 | 240 |
353 FT_EXPORT_DEF( FT_ListNode ) | 241 FT_EXPORT_DEF( FT_ListNode ) |
354 FT_List_Find( FT_List list, | 242 FT_List_Find( FT_List list, |
355 void* data ) | 243 void* data ) |
356 { | 244 { |
357 FT_ListNode cur; | 245 FT_ListNode cur; |
358 | 246 |
359 | 247 |
| 248 if ( !list ) |
| 249 return NULL; |
| 250 |
360 cur = list->head; | 251 cur = list->head; |
361 while ( cur ) | 252 while ( cur ) |
362 { | 253 { |
363 if ( cur->data == data ) | 254 if ( cur->data == data ) |
364 return cur; | 255 return cur; |
365 | 256 |
366 cur = cur->next; | 257 cur = cur->next; |
367 } | 258 } |
368 | 259 |
369 return (FT_ListNode)0; | 260 return NULL; |
370 } | 261 } |
371 | 262 |
372 | 263 |
373 /* documentation is in ftlist.h */ | 264 /* documentation is in ftlist.h */ |
374 | 265 |
375 FT_EXPORT_DEF( void ) | 266 FT_EXPORT_DEF( void ) |
376 FT_List_Add( FT_List list, | 267 FT_List_Add( FT_List list, |
377 FT_ListNode node ) | 268 FT_ListNode node ) |
378 { | 269 { |
379 FT_ListNode before = list->tail; | 270 FT_ListNode before; |
380 | 271 |
381 | 272 |
| 273 if ( !list || !node ) |
| 274 return; |
| 275 |
| 276 before = list->tail; |
| 277 |
382 node->next = 0; | 278 node->next = 0; |
383 node->prev = before; | 279 node->prev = before; |
384 | 280 |
385 if ( before ) | 281 if ( before ) |
386 before->next = node; | 282 before->next = node; |
387 else | 283 else |
388 list->head = node; | 284 list->head = node; |
389 | 285 |
390 list->tail = node; | 286 list->tail = node; |
391 } | 287 } |
392 | 288 |
393 | 289 |
394 /* documentation is in ftlist.h */ | 290 /* documentation is in ftlist.h */ |
395 | 291 |
396 FT_EXPORT_DEF( void ) | 292 FT_EXPORT_DEF( void ) |
397 FT_List_Insert( FT_List list, | 293 FT_List_Insert( FT_List list, |
398 FT_ListNode node ) | 294 FT_ListNode node ) |
399 { | 295 { |
400 FT_ListNode after = list->head; | 296 FT_ListNode after; |
401 | 297 |
402 | 298 |
| 299 if ( !list || !node ) |
| 300 return; |
| 301 |
| 302 after = list->head; |
| 303 |
403 node->next = after; | 304 node->next = after; |
404 node->prev = 0; | 305 node->prev = 0; |
405 | 306 |
406 if ( !after ) | 307 if ( !after ) |
407 list->tail = node; | 308 list->tail = node; |
408 else | 309 else |
409 after->prev = node; | 310 after->prev = node; |
410 | 311 |
411 list->head = node; | 312 list->head = node; |
412 } | 313 } |
413 | 314 |
414 | 315 |
415 /* documentation is in ftlist.h */ | 316 /* documentation is in ftlist.h */ |
416 | 317 |
417 FT_EXPORT_DEF( void ) | 318 FT_EXPORT_DEF( void ) |
418 FT_List_Remove( FT_List list, | 319 FT_List_Remove( FT_List list, |
419 FT_ListNode node ) | 320 FT_ListNode node ) |
420 { | 321 { |
421 FT_ListNode before, after; | 322 FT_ListNode before, after; |
422 | 323 |
423 | 324 |
| 325 if ( !list || !node ) |
| 326 return; |
| 327 |
424 before = node->prev; | 328 before = node->prev; |
425 after = node->next; | 329 after = node->next; |
426 | 330 |
427 if ( before ) | 331 if ( before ) |
428 before->next = after; | 332 before->next = after; |
429 else | 333 else |
430 list->head = after; | 334 list->head = after; |
431 | 335 |
432 if ( after ) | 336 if ( after ) |
433 after->prev = before; | 337 after->prev = before; |
434 else | 338 else |
435 list->tail = before; | 339 list->tail = before; |
436 } | 340 } |
437 | 341 |
438 | 342 |
439 /* documentation is in ftlist.h */ | 343 /* documentation is in ftlist.h */ |
440 | 344 |
441 FT_EXPORT_DEF( void ) | 345 FT_EXPORT_DEF( void ) |
442 FT_List_Up( FT_List list, | 346 FT_List_Up( FT_List list, |
443 FT_ListNode node ) | 347 FT_ListNode node ) |
444 { | 348 { |
445 FT_ListNode before, after; | 349 FT_ListNode before, after; |
446 | 350 |
447 | 351 |
| 352 if ( !list || !node ) |
| 353 return; |
| 354 |
448 before = node->prev; | 355 before = node->prev; |
449 after = node->next; | 356 after = node->next; |
450 | 357 |
451 /* check whether we are already on top of the list */ | 358 /* check whether we are already on top of the list */ |
452 if ( !before ) | 359 if ( !before ) |
453 return; | 360 return; |
454 | 361 |
455 before->next = after; | 362 before->next = after; |
456 | 363 |
457 if ( after ) | 364 if ( after ) |
458 after->prev = before; | 365 after->prev = before; |
459 else | 366 else |
460 list->tail = before; | 367 list->tail = before; |
461 | 368 |
462 node->prev = 0; | 369 node->prev = 0; |
463 node->next = list->head; | 370 node->next = list->head; |
464 list->head->prev = node; | 371 list->head->prev = node; |
465 list->head = node; | 372 list->head = node; |
466 } | 373 } |
467 | 374 |
468 | 375 |
469 /* documentation is in ftlist.h */ | 376 /* documentation is in ftlist.h */ |
470 | 377 |
471 FT_EXPORT_DEF( FT_Error ) | 378 FT_EXPORT_DEF( FT_Error ) |
472 FT_List_Iterate( FT_List list, | 379 FT_List_Iterate( FT_List list, |
473 FT_List_Iterator iterator, | 380 FT_List_Iterator iterator, |
474 void* user ) | 381 void* user ) |
475 { | 382 { |
476 FT_ListNode cur = list->head; | 383 FT_ListNode cur; |
477 FT_Error error = FT_Err_Ok; | 384 FT_Error error = FT_Err_Ok; |
478 | 385 |
479 | 386 |
| 387 if ( !list || !iterator ) |
| 388 return FT_THROW( Invalid_Argument ); |
| 389 |
| 390 cur = list->head; |
| 391 |
480 while ( cur ) | 392 while ( cur ) |
481 { | 393 { |
482 FT_ListNode next = cur->next; | 394 FT_ListNode next = cur->next; |
483 | 395 |
484 | 396 |
485 error = iterator( cur, user ); | 397 error = iterator( cur, user ); |
486 if ( error ) | 398 if ( error ) |
487 break; | 399 break; |
488 | 400 |
489 cur = next; | 401 cur = next; |
490 } | 402 } |
491 | 403 |
492 return error; | 404 return error; |
493 } | 405 } |
494 | 406 |
495 | 407 |
496 /* documentation is in ftlist.h */ | 408 /* documentation is in ftlist.h */ |
497 | 409 |
498 FT_EXPORT_DEF( void ) | 410 FT_EXPORT_DEF( void ) |
499 FT_List_Finalize( FT_List list, | 411 FT_List_Finalize( FT_List list, |
500 FT_List_Destructor destroy, | 412 FT_List_Destructor destroy, |
501 FT_Memory memory, | 413 FT_Memory memory, |
502 void* user ) | 414 void* user ) |
503 { | 415 { |
504 FT_ListNode cur; | 416 FT_ListNode cur; |
505 | 417 |
506 | 418 |
| 419 if ( !list || !memory ) |
| 420 return; |
| 421 |
507 cur = list->head; | 422 cur = list->head; |
508 while ( cur ) | 423 while ( cur ) |
509 { | 424 { |
510 FT_ListNode next = cur->next; | 425 FT_ListNode next = cur->next; |
511 void* data = cur->data; | 426 void* data = cur->data; |
512 | 427 |
513 | 428 |
514 if ( destroy ) | 429 if ( destroy ) |
515 destroy( memory, data, user ); | 430 destroy( memory, data, user ); |
516 | 431 |
517 FT_FREE( cur ); | 432 FT_FREE( cur ); |
518 cur = next; | 433 cur = next; |
519 } | 434 } |
520 | 435 |
521 list->head = 0; | 436 list->head = 0; |
522 list->tail = 0; | 437 list->tail = 0; |
523 } | 438 } |
524 | 439 |
525 | 440 |
526 FT_BASE_DEF( FT_UInt32 ) | |
527 ft_highpow2( FT_UInt32 value ) | |
528 { | |
529 FT_UInt32 value2; | |
530 | |
531 | |
532 /* | |
533 * We simply clear the lowest bit in each iteration. When | |
534 * we reach 0, we know that the previous value was our result. | |
535 */ | |
536 for ( ;; ) | |
537 { | |
538 value2 = value & (value - 1); /* clear lowest bit */ | |
539 if ( value2 == 0 ) | |
540 break; | |
541 | |
542 value = value2; | |
543 } | |
544 return value; | |
545 } | |
546 | |
547 | |
548 /* END */ | 441 /* END */ |
OLD | NEW |