1 /***************************************************************************/
5 /* FreeType utility functions for bitmaps (body). */
7 /* Copyright 2004-2009, 2011, 2013 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
20 #include FT_INTERNAL_DEBUG_H
24 #include FT_INTERNAL_OBJECTS_H
28 const FT_Bitmap null_bitmap
= { 0, 0, 0, 0, 0, 0, 0, 0 };
31 /* documentation is in ftbitmap.h */
34 FT_Bitmap_New( FT_Bitmap
*abitmap
)
36 *abitmap
= null_bitmap
;
40 /* documentation is in ftbitmap.h */
42 FT_EXPORT_DEF( FT_Error
)
43 FT_Bitmap_Copy( FT_Library library
,
44 const FT_Bitmap
*source
,
47 FT_Memory memory
= library
->memory
;
48 FT_Error error
= FT_Err_Ok
;
49 FT_Int pitch
= source
->pitch
;
53 if ( source
== target
)
56 if ( source
->buffer
== NULL
)
65 size
= (FT_ULong
)( pitch
* source
->rows
);
69 FT_Int target_pitch
= target
->pitch
;
73 if ( target_pitch
< 0 )
74 target_pitch
= -target_pitch
;
75 target_size
= (FT_ULong
)( target_pitch
* target
->rows
);
77 if ( target_size
!= size
)
78 (void)FT_QREALLOC( target
->buffer
, target_size
, size
);
81 (void)FT_QALLOC( target
->buffer
, size
);
92 FT_MEM_COPY( target
->buffer
, source
->buffer
, size
);
100 ft_bitmap_assure_buffer( FT_Memory memory
,
109 FT_Int i
, width
, height
;
110 unsigned char* buffer
= NULL
;
113 width
= bitmap
->width
;
114 height
= bitmap
->rows
;
115 pitch
= bitmap
->pitch
;
119 switch ( bitmap
->pixel_mode
)
121 case FT_PIXEL_MODE_MONO
:
123 new_pitch
= ( width
+ xpixels
+ 7 ) >> 3;
125 case FT_PIXEL_MODE_GRAY2
:
127 new_pitch
= ( width
+ xpixels
+ 3 ) >> 2;
129 case FT_PIXEL_MODE_GRAY4
:
131 new_pitch
= ( width
+ xpixels
+ 1 ) >> 1;
133 case FT_PIXEL_MODE_GRAY
:
134 case FT_PIXEL_MODE_LCD
:
135 case FT_PIXEL_MODE_LCD_V
:
137 new_pitch
= ( width
+ xpixels
);
140 return FT_THROW( Invalid_Glyph_Format
);
143 /* if no need to allocate memory */
144 if ( ypixels
== 0 && new_pitch
<= pitch
)
146 /* zero the padding */
147 FT_Int bit_width
= pitch
* 8;
148 FT_Int bit_last
= ( width
+ xpixels
) * bpp
;
151 if ( bit_last
< bit_width
)
153 FT_Byte
* line
= bitmap
->buffer
+ ( bit_last
>> 3 );
154 FT_Byte
* end
= bitmap
->buffer
+ pitch
;
155 FT_Int shift
= bit_last
& 7;
156 FT_UInt mask
= 0xFF00U
>> shift
;
157 FT_Int count
= height
;
160 for ( ; count
> 0; count
--, line
+= pitch
, end
+= pitch
)
162 FT_Byte
* write
= line
;
167 write
[0] = (FT_Byte
)( write
[0] & mask
);
171 FT_MEM_ZERO( write
, end
-write
);
178 if ( FT_QALLOC_MULT( buffer
, new_pitch
, bitmap
->rows
+ ypixels
) )
181 if ( bitmap
->pitch
> 0 )
183 FT_Int len
= ( width
* bpp
+ 7 ) >> 3;
186 for ( i
= 0; i
< bitmap
->rows
; i
++ )
187 FT_MEM_COPY( buffer
+ new_pitch
* ( ypixels
+ i
),
188 bitmap
->buffer
+ pitch
* i
, len
);
192 FT_Int len
= ( width
* bpp
+ 7 ) >> 3;
195 for ( i
= 0; i
< bitmap
->rows
; i
++ )
196 FT_MEM_COPY( buffer
+ new_pitch
* i
,
197 bitmap
->buffer
+ pitch
* i
, len
);
200 FT_FREE( bitmap
->buffer
);
201 bitmap
->buffer
= buffer
;
203 if ( bitmap
->pitch
< 0 )
204 new_pitch
= -new_pitch
;
206 /* set pitch only, width and height are left untouched */
207 bitmap
->pitch
= new_pitch
;
213 /* documentation is in ftbitmap.h */
215 FT_EXPORT_DEF( FT_Error
)
216 FT_Bitmap_Embolden( FT_Library library
,
223 FT_Int i
, x
, y
, pitch
;
228 return FT_THROW( Invalid_Library_Handle
);
230 if ( !bitmap
|| !bitmap
->buffer
)
231 return FT_THROW( Invalid_Argument
);
233 if ( ( ( FT_PIX_ROUND( xStrength
) >> 6 ) > FT_INT_MAX
) ||
234 ( ( FT_PIX_ROUND( yStrength
) >> 6 ) > FT_INT_MAX
) )
235 return FT_THROW( Invalid_Argument
);
237 xstr
= (FT_Int
)FT_PIX_ROUND( xStrength
) >> 6;
238 ystr
= (FT_Int
)FT_PIX_ROUND( yStrength
) >> 6;
240 if ( xstr
== 0 && ystr
== 0 )
242 else if ( xstr
< 0 || ystr
< 0 )
243 return FT_THROW( Invalid_Argument
);
245 switch ( bitmap
->pixel_mode
)
247 case FT_PIXEL_MODE_GRAY2
:
248 case FT_PIXEL_MODE_GRAY4
:
254 if ( bitmap
->pixel_mode
== FT_PIXEL_MODE_GRAY2
)
255 align
= ( bitmap
->width
+ xstr
+ 3 ) / 4;
257 align
= ( bitmap
->width
+ xstr
+ 1 ) / 2;
259 FT_Bitmap_New( &tmp
);
261 error
= FT_Bitmap_Convert( library
, bitmap
, &tmp
, align
);
265 FT_Bitmap_Done( library
, bitmap
);
270 case FT_PIXEL_MODE_MONO
:
275 case FT_PIXEL_MODE_LCD
:
279 case FT_PIXEL_MODE_LCD_V
:
283 case FT_PIXEL_MODE_BGRA
:
284 /* We don't embolden color glyphs. */
288 error
= ft_bitmap_assure_buffer( library
->memory
, bitmap
, xstr
, ystr
);
292 pitch
= bitmap
->pitch
;
294 p
= bitmap
->buffer
+ pitch
* ystr
;
298 p
= bitmap
->buffer
+ pitch
* ( bitmap
->rows
- 1 );
302 for ( y
= 0; y
< bitmap
->rows
; y
++ )
307 * From the last pixel on, make each pixel or'ed with the
308 * `xstr' pixels before it.
310 for ( x
= pitch
- 1; x
>= 0; x
-- )
316 for ( i
= 1; i
<= xstr
; i
++ )
318 if ( bitmap
->pixel_mode
== FT_PIXEL_MODE_MONO
)
322 /* the maximum value of 8 for `xstr' comes from here */
324 p
[x
] |= p
[x
- 1] << ( 8 - i
);
335 if ( p
[x
] + p
[x
- i
] > bitmap
->num_grays
- 1 )
337 p
[x
] = (unsigned char)(bitmap
->num_grays
- 1);
342 p
[x
] = (unsigned char)(p
[x
] + p
[x
-i
]);
343 if ( p
[x
] == bitmap
->num_grays
- 1 )
356 * Make the above `ystr' rows or'ed with it.
358 for ( x
= 1; x
<= ystr
; x
++ )
363 q
= p
- bitmap
->pitch
* x
;
364 for ( i
= 0; i
< pitch
; i
++ )
371 bitmap
->width
+= xstr
;
372 bitmap
->rows
+= ystr
;
379 ft_gray_for_premultiplied_srgb_bgra( const FT_Byte
* bgra
)
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.
394 * http://accessibility.kde.org/hsl-adjusted.php
396 * We do the computation with integers only.
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
);
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
);
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 */ );
418 * Final transparency can be determined this way:
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.
424 * So the formula is a * (1 - l).
427 return (FT_Byte
)( FT_MulFix( 65535 - l
, a
) >> 8 );
431 /* documentation is in ftbitmap.h */
433 FT_EXPORT_DEF( FT_Error
)
434 FT_Bitmap_Convert( FT_Library library
,
435 const FT_Bitmap
*source
,
439 FT_Error error
= FT_Err_Ok
;
444 return FT_THROW( Invalid_Library_Handle
);
446 memory
= library
->memory
;
448 switch ( source
->pixel_mode
)
450 case FT_PIXEL_MODE_MONO
:
451 case FT_PIXEL_MODE_GRAY
:
452 case FT_PIXEL_MODE_GRAY2
:
453 case FT_PIXEL_MODE_GRAY4
:
454 case FT_PIXEL_MODE_LCD
:
455 case FT_PIXEL_MODE_LCD_V
:
456 case FT_PIXEL_MODE_BGRA
:
462 old_size
= target
->rows
* target
->pitch
;
464 old_size
= -old_size
;
466 target
->pixel_mode
= FT_PIXEL_MODE_GRAY
;
467 target
->rows
= source
->rows
;
468 target
->width
= source
->width
;
473 pad
= source
->width
% alignment
;
475 pad
= alignment
- pad
;
478 target
->pitch
= source
->width
+ pad
;
480 if ( target
->pitch
> 0 &&
481 (FT_ULong
)target
->rows
> FT_ULONG_MAX
/ target
->pitch
)
482 return FT_THROW( Invalid_Argument
);
484 if ( target
->rows
* target
->pitch
> old_size
&&
485 FT_QREALLOC( target
->buffer
,
486 old_size
, target
->rows
* target
->pitch
) )
492 error
= FT_THROW( Invalid_Argument
);
495 switch ( source
->pixel_mode
)
497 case FT_PIXEL_MODE_MONO
:
499 FT_Byte
* s
= source
->buffer
;
500 FT_Byte
* t
= target
->buffer
;
504 target
->num_grays
= 2;
506 for ( i
= source
->rows
; i
> 0; i
-- )
513 /* get the full bytes */
514 for ( j
= source
->width
>> 3; j
> 0; j
-- )
516 FT_Int val
= ss
[0]; /* avoid a byte->int cast on each line */
518 tt
[0] = (FT_Byte
)( ( val
& 0x80 ) ? 0xff : 0);
519 tt
[1] = (FT_Byte
)( ( val
& 0x40 ) ? 0xff : 0);
520 tt
[2] = (FT_Byte
)( ( val
& 0x20 ) ? 0xff : 0);
521 tt
[3] = (FT_Byte
)( ( val
& 0x10 ) ? 0xff : 0);
522 tt
[4] = (FT_Byte
)( ( val
& 0x08 ) ? 0xff : 0);
523 tt
[5] = (FT_Byte
)( ( val
& 0x04 ) ? 0xff : 0);
524 tt
[6] = (FT_Byte
)( ( val
& 0x02 ) ? 0xff : 0);
525 tt
[7] = (FT_Byte
)( ( val
& 0x01 ) ? 0xff : 0);
532 /* get remaining pixels (if any) */
533 j
= source
->width
& 7;
541 tt
[0] = (FT_Byte
)( ( val
& 0x80 ) ? 0xff : 0);
554 case FT_PIXEL_MODE_GRAY
:
555 case FT_PIXEL_MODE_LCD
:
556 case FT_PIXEL_MODE_LCD_V
:
558 FT_Int width
= source
->width
;
559 FT_Byte
* s
= source
->buffer
;
560 FT_Byte
* t
= target
->buffer
;
561 FT_Int s_pitch
= source
->pitch
;
562 FT_Int t_pitch
= target
->pitch
;
566 target
->num_grays
= 256;
568 for ( i
= source
->rows
; i
> 0; i
-- )
570 FT_ARRAY_COPY( t
, s
, width
);
579 case FT_PIXEL_MODE_GRAY2
:
581 FT_Byte
* s
= source
->buffer
;
582 FT_Byte
* t
= target
->buffer
;
586 target
->num_grays
= 4;
588 for ( i
= source
->rows
; i
> 0; i
-- )
595 /* get the full bytes */
596 for ( j
= source
->width
>> 2; j
> 0; j
-- )
601 tt
[0] = (FT_Byte
)( ( val
& 0xC0 ) >> 6 );
602 tt
[1] = (FT_Byte
)( ( val
& 0x30 ) >> 4 );
603 tt
[2] = (FT_Byte
)( ( val
& 0x0C ) >> 2 );
604 tt
[3] = (FT_Byte
)( ( val
& 0x03 ) );
610 j
= source
->width
& 3;
618 tt
[0] = (FT_Byte
)( ( val
& 0xC0 ) >> 6 );
631 case FT_PIXEL_MODE_GRAY4
:
633 FT_Byte
* s
= source
->buffer
;
634 FT_Byte
* t
= target
->buffer
;
638 target
->num_grays
= 16;
640 for ( i
= source
->rows
; i
> 0; i
-- )
647 /* get the full bytes */
648 for ( j
= source
->width
>> 1; j
> 0; j
-- )
653 tt
[0] = (FT_Byte
)( ( val
& 0xF0 ) >> 4 );
654 tt
[1] = (FT_Byte
)( ( val
& 0x0F ) );
660 if ( source
->width
& 1 )
661 tt
[0] = (FT_Byte
)( ( ss
[0] & 0xF0 ) >> 4 );
669 case FT_PIXEL_MODE_BGRA
:
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
;
678 target
->num_grays
= 256;
680 for ( i
= source
->rows
; i
> 0; i
-- )
687 for ( j
= source
->width
; j
> 0; j
-- )
689 tt
[0] = ft_gray_for_premultiplied_srgb_bgra( ss
);
709 /* documentation is in ftbitmap.h */
711 FT_EXPORT_DEF( FT_Error
)
712 FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot
)
714 if ( slot
&& slot
->format
== FT_GLYPH_FORMAT_BITMAP
&&
715 !( slot
->internal
->flags
& FT_GLYPH_OWN_BITMAP
) )
721 FT_Bitmap_New( &bitmap
);
722 error
= FT_Bitmap_Copy( slot
->library
, &slot
->bitmap
, &bitmap
);
726 slot
->bitmap
= bitmap
;
727 slot
->internal
->flags
|= FT_GLYPH_OWN_BITMAP
;
734 /* documentation is in ftbitmap.h */
736 FT_EXPORT_DEF( FT_Error
)
737 FT_Bitmap_Done( FT_Library library
,
744 return FT_THROW( Invalid_Library_Handle
);
747 return FT_THROW( Invalid_Argument
);
749 memory
= library
->memory
;
751 FT_FREE( bitmap
->buffer
);
752 *bitmap
= null_bitmap
;