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 |