| OLD | NEW |
| 1 /***************************************************************************/ | 1 /***************************************************************************/ |
| 2 /* */ | 2 /* */ |
| 3 /* ftbitmap.c */ | 3 /* ftbitmap.c */ |
| 4 /* */ | 4 /* */ |
| 5 /* FreeType utility functions for bitmaps (body). */ | 5 /* FreeType utility functions for bitmaps (body). */ |
| 6 /* */ | 6 /* */ |
| 7 /* Copyright 2004-2009, 2011 by */ | 7 /* Copyright 2004-2009, 2011, 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 <ft2build.h> | 19 #include <ft2build.h> |
| 20 #include FT_INTERNAL_DEBUG_H |
| 21 |
| 20 #include FT_BITMAP_H | 22 #include FT_BITMAP_H |
| 21 #include FT_IMAGE_H | 23 #include FT_IMAGE_H |
| 22 #include FT_INTERNAL_OBJECTS_H | 24 #include FT_INTERNAL_OBJECTS_H |
| 23 | 25 |
| 24 | 26 |
| 25 static | 27 static |
| 26 const FT_Bitmap null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 }; | 28 const FT_Bitmap null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 27 | 29 |
| 28 | 30 |
| 29 /* documentation is in ftbitmap.h */ | 31 /* documentation is in ftbitmap.h */ |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 bpp = 4; | 130 bpp = 4; |
| 129 new_pitch = ( width + xpixels + 1 ) >> 1; | 131 new_pitch = ( width + xpixels + 1 ) >> 1; |
| 130 break; | 132 break; |
| 131 case FT_PIXEL_MODE_GRAY: | 133 case FT_PIXEL_MODE_GRAY: |
| 132 case FT_PIXEL_MODE_LCD: | 134 case FT_PIXEL_MODE_LCD: |
| 133 case FT_PIXEL_MODE_LCD_V: | 135 case FT_PIXEL_MODE_LCD_V: |
| 134 bpp = 8; | 136 bpp = 8; |
| 135 new_pitch = ( width + xpixels ); | 137 new_pitch = ( width + xpixels ); |
| 136 break; | 138 break; |
| 137 default: | 139 default: |
| 138 return FT_Err_Invalid_Glyph_Format; | 140 return FT_THROW( Invalid_Glyph_Format ); |
| 139 } | 141 } |
| 140 | 142 |
| 141 /* if no need to allocate memory */ | 143 /* if no need to allocate memory */ |
| 142 if ( ypixels == 0 && new_pitch <= pitch ) | 144 if ( ypixels == 0 && new_pitch <= pitch ) |
| 143 { | 145 { |
| 144 /* zero the padding */ | 146 /* zero the padding */ |
| 145 FT_Int bit_width = pitch * 8; | 147 FT_Int bit_width = pitch * 8; |
| 146 FT_Int bit_last = ( width + xpixels ) * bpp; | 148 FT_Int bit_last = ( width + xpixels ) * bpp; |
| 147 | 149 |
| 148 | 150 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 FT_Pos xStrength, | 218 FT_Pos xStrength, |
| 217 FT_Pos yStrength ) | 219 FT_Pos yStrength ) |
| 218 { | 220 { |
| 219 FT_Error error; | 221 FT_Error error; |
| 220 unsigned char* p; | 222 unsigned char* p; |
| 221 FT_Int i, x, y, pitch; | 223 FT_Int i, x, y, pitch; |
| 222 FT_Int xstr, ystr; | 224 FT_Int xstr, ystr; |
| 223 | 225 |
| 224 | 226 |
| 225 if ( !library ) | 227 if ( !library ) |
| 226 return FT_Err_Invalid_Library_Handle; | 228 return FT_THROW( Invalid_Library_Handle ); |
| 227 | 229 |
| 228 if ( !bitmap || !bitmap->buffer ) | 230 if ( !bitmap || !bitmap->buffer ) |
| 229 return FT_Err_Invalid_Argument; | 231 return FT_THROW( Invalid_Argument ); |
| 230 | 232 |
| 231 if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) || | 233 if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) || |
| 232 ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) ) | 234 ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) ) |
| 233 return FT_Err_Invalid_Argument; | 235 return FT_THROW( Invalid_Argument ); |
| 234 | 236 |
| 235 xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6; | 237 xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6; |
| 236 ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6; | 238 ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6; |
| 237 | 239 |
| 238 if ( xstr == 0 && ystr == 0 ) | 240 if ( xstr == 0 && ystr == 0 ) |
| 239 return FT_Err_Ok; | 241 return FT_Err_Ok; |
| 240 else if ( xstr < 0 || ystr < 0 ) | 242 else if ( xstr < 0 || ystr < 0 ) |
| 241 return FT_Err_Invalid_Argument; | 243 return FT_THROW( Invalid_Argument ); |
| 242 | 244 |
| 243 switch ( bitmap->pixel_mode ) | 245 switch ( bitmap->pixel_mode ) |
| 244 { | 246 { |
| 245 case FT_PIXEL_MODE_GRAY2: | 247 case FT_PIXEL_MODE_GRAY2: |
| 246 case FT_PIXEL_MODE_GRAY4: | 248 case FT_PIXEL_MODE_GRAY4: |
| 247 { | 249 { |
| 248 FT_Bitmap tmp; | 250 FT_Bitmap tmp; |
| 249 FT_Int align; | 251 FT_Int align; |
| 250 | 252 |
| 251 | 253 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 270 xstr = 8; | 272 xstr = 8; |
| 271 break; | 273 break; |
| 272 | 274 |
| 273 case FT_PIXEL_MODE_LCD: | 275 case FT_PIXEL_MODE_LCD: |
| 274 xstr *= 3; | 276 xstr *= 3; |
| 275 break; | 277 break; |
| 276 | 278 |
| 277 case FT_PIXEL_MODE_LCD_V: | 279 case FT_PIXEL_MODE_LCD_V: |
| 278 ystr *= 3; | 280 ystr *= 3; |
| 279 break; | 281 break; |
| 282 |
| 283 case FT_PIXEL_MODE_BGRA: |
| 284 /* We don't embolden color glyphs. */ |
| 285 return FT_Err_Ok; |
| 280 } | 286 } |
| 281 | 287 |
| 282 error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr ); | 288 error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr ); |
| 283 if ( error ) | 289 if ( error ) |
| 284 return error; | 290 return error; |
| 285 | 291 |
| 286 pitch = bitmap->pitch; | 292 pitch = bitmap->pitch; |
| 287 if ( pitch > 0 ) | 293 if ( pitch > 0 ) |
| 288 p = bitmap->buffer + pitch * ystr; | 294 p = bitmap->buffer + pitch * ystr; |
| 289 else | 295 else |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 p += bitmap->pitch; | 368 p += bitmap->pitch; |
| 363 } | 369 } |
| 364 | 370 |
| 365 bitmap->width += xstr; | 371 bitmap->width += xstr; |
| 366 bitmap->rows += ystr; | 372 bitmap->rows += ystr; |
| 367 | 373 |
| 368 return FT_Err_Ok; | 374 return FT_Err_Ok; |
| 369 } | 375 } |
| 370 | 376 |
| 371 | 377 |
| 378 FT_Byte |
| 379 ft_gray_for_premultiplied_srgb_bgra( const FT_Byte* bgra ) |
| 380 { |
| 381 FT_Long a = bgra[3]; |
| 382 FT_Long b = bgra[0]; |
| 383 FT_Long g = bgra[1]; |
| 384 FT_Long r = bgra[2]; |
| 385 FT_Long l; |
| 386 |
| 387 |
| 388 /* |
| 389 * Luminosity for sRGB is defined using ~0.2126,0.7152,0.0722 |
| 390 * coefficients for RGB channels *on the linear colors*. |
| 391 * A gamma of 2.2 is fair to assume. And then, we need to |
| 392 * undo the premultiplication too. |
| 393 * |
| 394 * http://accessibility.kde.org/hsl-adjusted.php |
| 395 * |
| 396 * We do the computation with integers only. |
| 397 */ |
| 398 |
| 399 /* Undo premultification, get the number in a 16.16 form. */ |
| 400 b = FT_MulDiv( b, 65536, a ); |
| 401 g = FT_MulDiv( g, 65536, a ); |
| 402 r = FT_MulDiv( r, 65536, a ); |
| 403 a = a * 256; |
| 404 |
| 405 /* Apply gamma of 2.0 instead of 2.2. */ |
| 406 b = FT_MulFix( b, b ); |
| 407 g = FT_MulFix( g, g ); |
| 408 r = FT_MulFix( r, r ); |
| 409 |
| 410 /* Apply coefficients. */ |
| 411 b = FT_MulFix( b, 4731 /* 0.0722 * 65536 */ ); |
| 412 g = FT_MulFix( g, 46871 /* 0.7152 * 65536 */ ); |
| 413 r = FT_MulFix( r, 13933 /* 0.2126 * 65536 */ ); |
| 414 |
| 415 l = r + g + b; |
| 416 |
| 417 /* |
| 418 * Final transparency can be determined this way: |
| 419 * |
| 420 * - If alpha is zero, we want 0. |
| 421 * - If alpha is zero and luminosity is zero, we want 255. |
| 422 * - If alpha is zero and luminosity is one, we want 0. |
| 423 * |
| 424 * So the formula is a * (1 - l). |
| 425 */ |
| 426 |
| 427 return (FT_Byte)( FT_MulFix( 65535 - l, a ) >> 8 ); |
| 428 } |
| 429 |
| 430 |
| 372 /* documentation is in ftbitmap.h */ | 431 /* documentation is in ftbitmap.h */ |
| 373 | 432 |
| 374 FT_EXPORT_DEF( FT_Error ) | 433 FT_EXPORT_DEF( FT_Error ) |
| 375 FT_Bitmap_Convert( FT_Library library, | 434 FT_Bitmap_Convert( FT_Library library, |
| 376 const FT_Bitmap *source, | 435 const FT_Bitmap *source, |
| 377 FT_Bitmap *target, | 436 FT_Bitmap *target, |
| 378 FT_Int alignment ) | 437 FT_Int alignment ) |
| 379 { | 438 { |
| 380 FT_Error error = FT_Err_Ok; | 439 FT_Error error = FT_Err_Ok; |
| 381 FT_Memory memory; | 440 FT_Memory memory; |
| 382 | 441 |
| 383 | 442 |
| 384 if ( !library ) | 443 if ( !library ) |
| 385 return FT_Err_Invalid_Library_Handle; | 444 return FT_THROW( Invalid_Library_Handle ); |
| 386 | 445 |
| 387 memory = library->memory; | 446 memory = library->memory; |
| 388 | 447 |
| 389 switch ( source->pixel_mode ) | 448 switch ( source->pixel_mode ) |
| 390 { | 449 { |
| 391 case FT_PIXEL_MODE_MONO: | 450 case FT_PIXEL_MODE_MONO: |
| 392 case FT_PIXEL_MODE_GRAY: | 451 case FT_PIXEL_MODE_GRAY: |
| 393 case FT_PIXEL_MODE_GRAY2: | 452 case FT_PIXEL_MODE_GRAY2: |
| 394 case FT_PIXEL_MODE_GRAY4: | 453 case FT_PIXEL_MODE_GRAY4: |
| 395 case FT_PIXEL_MODE_LCD: | 454 case FT_PIXEL_MODE_LCD: |
| 396 case FT_PIXEL_MODE_LCD_V: | 455 case FT_PIXEL_MODE_LCD_V: |
| 456 case FT_PIXEL_MODE_BGRA: |
| 397 { | 457 { |
| 398 FT_Int pad; | 458 FT_Int pad; |
| 399 FT_Long old_size; | 459 FT_Long old_size; |
| 400 | 460 |
| 401 | 461 |
| 402 old_size = target->rows * target->pitch; | 462 old_size = target->rows * target->pitch; |
| 403 if ( old_size < 0 ) | 463 if ( old_size < 0 ) |
| 404 old_size = -old_size; | 464 old_size = -old_size; |
| 405 | 465 |
| 406 target->pixel_mode = FT_PIXEL_MODE_GRAY; | 466 target->pixel_mode = FT_PIXEL_MODE_GRAY; |
| 407 target->rows = source->rows; | 467 target->rows = source->rows; |
| 408 target->width = source->width; | 468 target->width = source->width; |
| 409 | 469 |
| 410 pad = 0; | 470 pad = 0; |
| 411 if ( alignment > 0 ) | 471 if ( alignment > 0 ) |
| 412 { | 472 { |
| 413 pad = source->width % alignment; | 473 pad = source->width % alignment; |
| 414 if ( pad != 0 ) | 474 if ( pad != 0 ) |
| 415 pad = alignment - pad; | 475 pad = alignment - pad; |
| 416 } | 476 } |
| 417 | 477 |
| 418 target->pitch = source->width + pad; | 478 target->pitch = source->width + pad; |
| 419 | 479 |
| 420 if ( target->pitch > 0 && | 480 if ( target->pitch > 0 && |
| 421 (FT_ULong)target->rows > FT_ULONG_MAX / target->pitch ) | 481 (FT_ULong)target->rows > FT_ULONG_MAX / target->pitch ) |
| 422 return FT_Err_Invalid_Argument; | 482 return FT_THROW( Invalid_Argument ); |
| 423 | 483 |
| 424 if ( target->rows * target->pitch > old_size && | 484 if ( target->rows * target->pitch > old_size && |
| 425 FT_QREALLOC( target->buffer, | 485 FT_QREALLOC( target->buffer, |
| 426 old_size, target->rows * target->pitch ) ) | 486 old_size, target->rows * target->pitch ) ) |
| 427 return error; | 487 return error; |
| 428 } | 488 } |
| 429 break; | 489 break; |
| 430 | 490 |
| 431 default: | 491 default: |
| 432 error = FT_Err_Invalid_Argument; | 492 error = FT_THROW( Invalid_Argument ); |
| 433 } | 493 } |
| 434 | 494 |
| 435 switch ( source->pixel_mode ) | 495 switch ( source->pixel_mode ) |
| 436 { | 496 { |
| 437 case FT_PIXEL_MODE_MONO: | 497 case FT_PIXEL_MODE_MONO: |
| 438 { | 498 { |
| 439 FT_Byte* s = source->buffer; | 499 FT_Byte* s = source->buffer; |
| 440 FT_Byte* t = target->buffer; | 500 FT_Byte* t = target->buffer; |
| 441 FT_Int i; | 501 FT_Int i; |
| 442 | 502 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 | 659 |
| 600 if ( source->width & 1 ) | 660 if ( source->width & 1 ) |
| 601 tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 ); | 661 tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 ); |
| 602 | 662 |
| 603 s += source->pitch; | 663 s += source->pitch; |
| 604 t += target->pitch; | 664 t += target->pitch; |
| 605 } | 665 } |
| 606 } | 666 } |
| 607 break; | 667 break; |
| 608 | 668 |
| 669 case FT_PIXEL_MODE_BGRA: |
| 670 { |
| 671 FT_Byte* s = source->buffer; |
| 672 FT_Byte* t = target->buffer; |
| 673 FT_Int s_pitch = source->pitch; |
| 674 FT_Int t_pitch = target->pitch; |
| 675 FT_Int i; |
| 676 |
| 677 |
| 678 target->num_grays = 256; |
| 679 |
| 680 for ( i = source->rows; i > 0; i-- ) |
| 681 { |
| 682 FT_Byte* ss = s; |
| 683 FT_Byte* tt = t; |
| 684 FT_Int j; |
| 685 |
| 686 |
| 687 for ( j = source->width; j > 0; j-- ) |
| 688 { |
| 689 tt[0] = ft_gray_for_premultiplied_srgb_bgra( ss ); |
| 690 |
| 691 ss += 4; |
| 692 tt += 1; |
| 693 } |
| 694 |
| 695 s += s_pitch; |
| 696 t += t_pitch; |
| 697 } |
| 698 } |
| 699 break; |
| 609 | 700 |
| 610 default: | 701 default: |
| 611 ; | 702 ; |
| 612 } | 703 } |
| 613 | 704 |
| 614 return error; | 705 return error; |
| 615 } | 706 } |
| 616 | 707 |
| 617 | 708 |
| 618 /* documentation is in ftbitmap.h */ | 709 /* documentation is in ftbitmap.h */ |
| (...skipping 24 matching lines...) Expand all Loading... |
| 643 /* documentation is in ftbitmap.h */ | 734 /* documentation is in ftbitmap.h */ |
| 644 | 735 |
| 645 FT_EXPORT_DEF( FT_Error ) | 736 FT_EXPORT_DEF( FT_Error ) |
| 646 FT_Bitmap_Done( FT_Library library, | 737 FT_Bitmap_Done( FT_Library library, |
| 647 FT_Bitmap *bitmap ) | 738 FT_Bitmap *bitmap ) |
| 648 { | 739 { |
| 649 FT_Memory memory; | 740 FT_Memory memory; |
| 650 | 741 |
| 651 | 742 |
| 652 if ( !library ) | 743 if ( !library ) |
| 653 return FT_Err_Invalid_Library_Handle; | 744 return FT_THROW( Invalid_Library_Handle ); |
| 654 | 745 |
| 655 if ( !bitmap ) | 746 if ( !bitmap ) |
| 656 return FT_Err_Invalid_Argument; | 747 return FT_THROW( Invalid_Argument ); |
| 657 | 748 |
| 658 memory = library->memory; | 749 memory = library->memory; |
| 659 | 750 |
| 660 FT_FREE( bitmap->buffer ); | 751 FT_FREE( bitmap->buffer ); |
| 661 *bitmap = null_bitmap; | 752 *bitmap = null_bitmap; |
| 662 | 753 |
| 663 return FT_Err_Ok; | 754 return FT_Err_Ok; |
| 664 } | 755 } |
| 665 | 756 |
| 666 | 757 |
| 667 /* END */ | 758 /* END */ |
| OLD | NEW |