| 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 |