1 /***************************************************************************/
5 /* FreeType utility functions for bitmaps (body). */
7 /* Copyright 2004-2009, 2011, 2013, 2014 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
)
388 /* Short-circuit transparent color to avoid div-by-zero. */
393 * Luminosity for sRGB is defined using ~0.2126,0.7152,0.0722
394 * coefficients for RGB channels *on the linear colors*.
395 * A gamma of 2.2 is fair to assume. And then, we need to
396 * undo the premultiplication too.
398 * http://accessibility.kde.org/hsl-adjusted.php
400 * We do the computation with integers only.
403 /* Undo premultification, get the number in a 16.16 form. */
404 b
= FT_MulDiv( b
, 65536, a
);
405 g
= FT_MulDiv( g
, 65536, a
);
406 r
= FT_MulDiv( r
, 65536, a
);
409 /* Apply gamma of 2.0 instead of 2.2. */
410 b
= FT_MulFix( b
, b
);
411 g
= FT_MulFix( g
, g
);
412 r
= FT_MulFix( r
, r
);
414 /* Apply coefficients. */
415 b
= FT_MulFix( b
, 4731 /* 0.0722 * 65536 */ );
416 g
= FT_MulFix( g
, 46871 /* 0.7152 * 65536 */ );
417 r
= FT_MulFix( r
, 13933 /* 0.2126 * 65536 */ );
422 * Final transparency can be determined this way:
424 * - If alpha is zero, we want 0.
425 * - If alpha is zero and luminosity is zero, we want 255.
426 * - If alpha is zero and luminosity is one, we want 0.
428 * So the formula is a * (1 - l).
431 return (FT_Byte
)( FT_MulFix( 65535 - l
, a
) >> 8 );
435 /* documentation is in ftbitmap.h */
437 FT_EXPORT_DEF( FT_Error
)
438 FT_Bitmap_Convert( FT_Library library
,
439 const FT_Bitmap
*source
,
443 FT_Error error
= FT_Err_Ok
;
448 return FT_THROW( Invalid_Library_Handle
);
450 memory
= library
->memory
;
452 switch ( source
->pixel_mode
)
454 case FT_PIXEL_MODE_MONO
:
455 case FT_PIXEL_MODE_GRAY
:
456 case FT_PIXEL_MODE_GRAY2
:
457 case FT_PIXEL_MODE_GRAY4
:
458 case FT_PIXEL_MODE_LCD
:
459 case FT_PIXEL_MODE_LCD_V
:
460 case FT_PIXEL_MODE_BGRA
:
466 old_size
= target
->rows
* target
->pitch
;
468 old_size
= -old_size
;
470 target
->pixel_mode
= FT_PIXEL_MODE_GRAY
;
471 target
->rows
= source
->rows
;
472 target
->width
= source
->width
;
477 pad
= source
->width
% alignment
;
479 pad
= alignment
- pad
;
482 target
->pitch
= source
->width
+ pad
;
484 if ( target
->pitch
> 0 &&
485 (FT_ULong
)target
->rows
> FT_ULONG_MAX
/ target
->pitch
)
486 return FT_THROW( Invalid_Argument
);
488 if ( target
->rows
* target
->pitch
> old_size
&&
489 FT_QREALLOC( target
->buffer
,
490 old_size
, target
->rows
* target
->pitch
) )
496 error
= FT_THROW( Invalid_Argument
);
499 switch ( source
->pixel_mode
)
501 case FT_PIXEL_MODE_MONO
:
503 FT_Byte
* s
= source
->buffer
;
504 FT_Byte
* t
= target
->buffer
;
508 target
->num_grays
= 2;
510 for ( i
= source
->rows
; i
> 0; i
-- )
517 /* get the full bytes */
518 for ( j
= source
->width
>> 3; j
> 0; j
-- )
520 FT_Int val
= ss
[0]; /* avoid a byte->int cast on each line */
522 tt
[0] = (FT_Byte
)( ( val
& 0x80 ) ? 0xff : 0);
523 tt
[1] = (FT_Byte
)( ( val
& 0x40 ) ? 0xff : 0);
524 tt
[2] = (FT_Byte
)( ( val
& 0x20 ) ? 0xff : 0);
525 tt
[3] = (FT_Byte
)( ( val
& 0x10 ) ? 0xff : 0);
526 tt
[4] = (FT_Byte
)( ( val
& 0x08 ) ? 0xff : 0);
527 tt
[5] = (FT_Byte
)( ( val
& 0x04 ) ? 0xff : 0);
528 tt
[6] = (FT_Byte
)( ( val
& 0x02 ) ? 0xff : 0);
529 tt
[7] = (FT_Byte
)( ( val
& 0x01 ) ? 0xff : 0);
536 /* get remaining pixels (if any) */
537 j
= source
->width
& 7;
545 tt
[0] = (FT_Byte
)( ( val
& 0x80 ) ? 0xff : 0);
558 case FT_PIXEL_MODE_GRAY
:
559 case FT_PIXEL_MODE_LCD
:
560 case FT_PIXEL_MODE_LCD_V
:
562 FT_Int width
= source
->width
;
563 FT_Byte
* s
= source
->buffer
;
564 FT_Byte
* t
= target
->buffer
;
565 FT_Int s_pitch
= source
->pitch
;
566 FT_Int t_pitch
= target
->pitch
;
570 target
->num_grays
= 256;
572 for ( i
= source
->rows
; i
> 0; i
-- )
574 FT_ARRAY_COPY( t
, s
, width
);
583 case FT_PIXEL_MODE_GRAY2
:
585 FT_Byte
* s
= source
->buffer
;
586 FT_Byte
* t
= target
->buffer
;
590 target
->num_grays
= 4;
592 for ( i
= source
->rows
; i
> 0; i
-- )
599 /* get the full bytes */
600 for ( j
= source
->width
>> 2; j
> 0; j
-- )
605 tt
[0] = (FT_Byte
)( ( val
& 0xC0 ) >> 6 );
606 tt
[1] = (FT_Byte
)( ( val
& 0x30 ) >> 4 );
607 tt
[2] = (FT_Byte
)( ( val
& 0x0C ) >> 2 );
608 tt
[3] = (FT_Byte
)( ( val
& 0x03 ) );
614 j
= source
->width
& 3;
622 tt
[0] = (FT_Byte
)( ( val
& 0xC0 ) >> 6 );
635 case FT_PIXEL_MODE_GRAY4
:
637 FT_Byte
* s
= source
->buffer
;
638 FT_Byte
* t
= target
->buffer
;
642 target
->num_grays
= 16;
644 for ( i
= source
->rows
; i
> 0; i
-- )
651 /* get the full bytes */
652 for ( j
= source
->width
>> 1; j
> 0; j
-- )
657 tt
[0] = (FT_Byte
)( ( val
& 0xF0 ) >> 4 );
658 tt
[1] = (FT_Byte
)( ( val
& 0x0F ) );
664 if ( source
->width
& 1 )
665 tt
[0] = (FT_Byte
)( ( ss
[0] & 0xF0 ) >> 4 );
673 case FT_PIXEL_MODE_BGRA
:
675 FT_Byte
* s
= source
->buffer
;
676 FT_Byte
* t
= target
->buffer
;
677 FT_Int s_pitch
= source
->pitch
;
678 FT_Int t_pitch
= target
->pitch
;
682 target
->num_grays
= 256;
684 for ( i
= source
->rows
; i
> 0; i
-- )
691 for ( j
= source
->width
; j
> 0; j
-- )
693 tt
[0] = ft_gray_for_premultiplied_srgb_bgra( ss
);
713 /* documentation is in ftbitmap.h */
715 FT_EXPORT_DEF( FT_Error
)
716 FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot
)
718 if ( slot
&& slot
->format
== FT_GLYPH_FORMAT_BITMAP
&&
719 !( slot
->internal
->flags
& FT_GLYPH_OWN_BITMAP
) )
725 FT_Bitmap_New( &bitmap
);
726 error
= FT_Bitmap_Copy( slot
->library
, &slot
->bitmap
, &bitmap
);
730 slot
->bitmap
= bitmap
;
731 slot
->internal
->flags
|= FT_GLYPH_OWN_BITMAP
;
738 /* documentation is in ftbitmap.h */
740 FT_EXPORT_DEF( FT_Error
)
741 FT_Bitmap_Done( FT_Library library
,
748 return FT_THROW( Invalid_Library_Handle
);
751 return FT_THROW( Invalid_Argument
);
753 memory
= library
->memory
;
755 FT_FREE( bitmap
->buffer
);
756 *bitmap
= null_bitmap
;