1 /***************************************************************************/
5 /* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */
6 /* bitmaps into 8bpp format (body). */
8 /* Copyright 2004, 2005, 2006, 2007 by */
9 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
11 /* This file is part of the FreeType project, and may only be used, */
12 /* modified, and distributed under the terms of the FreeType project */
13 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
14 /* this file you indicate that you have read the license and */
15 /* understand and accept it fully. */
17 /***************************************************************************/
22 #include FT_INTERNAL_OBJECTS_H
26 const FT_Bitmap null_bitmap
= { 0, 0, 0, 0, 0, 0, 0, 0 };
29 /* documentation is in ftbitmap.h */
32 FT_Bitmap_New( FT_Bitmap
*abitmap
)
34 *abitmap
= null_bitmap
;
38 /* documentation is in ftbitmap.h */
40 FT_EXPORT_DEF( FT_Error
)
41 FT_Bitmap_Copy( FT_Library library
,
42 const FT_Bitmap
*source
,
45 FT_Memory memory
= library
->memory
;
46 FT_Error error
= FT_Err_Ok
;
47 FT_Int pitch
= source
->pitch
;
51 if ( source
== target
)
54 if ( source
->buffer
== NULL
)
63 size
= (FT_ULong
)( pitch
* source
->rows
);
67 FT_Int target_pitch
= target
->pitch
;
71 if ( target_pitch
< 0 )
72 target_pitch
= -target_pitch
;
73 target_size
= (FT_ULong
)( target_pitch
* target
->rows
);
75 if ( target_size
!= size
)
76 (void)FT_QREALLOC( target
->buffer
, target_size
, size
);
79 (void)FT_QALLOC( target
->buffer
, size
);
90 FT_MEM_COPY( target
->buffer
, source
->buffer
, size
);
98 ft_bitmap_assure_buffer( FT_Memory memory
,
107 FT_Int i
, width
, height
;
108 unsigned char* buffer
;
111 width
= bitmap
->width
;
112 height
= bitmap
->rows
;
113 pitch
= bitmap
->pitch
;
117 switch ( bitmap
->pixel_mode
)
119 case FT_PIXEL_MODE_MONO
:
121 new_pitch
= ( width
+ xpixels
+ 7 ) >> 3;
123 case FT_PIXEL_MODE_GRAY2
:
125 new_pitch
= ( width
+ xpixels
+ 3 ) >> 2;
127 case FT_PIXEL_MODE_GRAY4
:
129 new_pitch
= ( width
+ xpixels
+ 1 ) >> 1;
131 case FT_PIXEL_MODE_GRAY
:
132 case FT_PIXEL_MODE_LCD
:
133 case FT_PIXEL_MODE_LCD_V
:
135 new_pitch
= ( width
+ xpixels
);
138 return FT_Err_Invalid_Glyph_Format
;
141 /* if no need to allocate memory */
142 if ( ypixels
== 0 && new_pitch
<= pitch
)
144 /* zero the padding */
145 FT_Int bit_width
= pitch
* 8;
146 FT_Int bit_last
= ( width
+ xpixels
) * bpp
;
149 if ( bit_last
< bit_width
)
151 FT_Byte
* line
= bitmap
->buffer
+ ( bit_last
>> 3 );
152 FT_Byte
* end
= bitmap
->buffer
+ pitch
;
153 FT_Int shift
= bit_last
& 7;
154 FT_UInt mask
= 0xFF00U
>> shift
;
155 FT_Int count
= height
;
158 for ( ; count
> 0; count
--, line
+= pitch
, end
+= pitch
)
160 FT_Byte
* write
= line
;
165 write
[0] = (FT_Byte
)( write
[0] & mask
);
169 FT_MEM_ZERO( write
, end
-write
);
176 if ( FT_QALLOC_MULT( buffer
, new_pitch
, bitmap
->rows
+ ypixels
) )
179 if ( bitmap
->pitch
> 0 )
181 FT_Int len
= ( width
* bpp
+ 7 ) >> 3;
184 for ( i
= 0; i
< bitmap
->rows
; i
++ )
185 FT_MEM_COPY( buffer
+ new_pitch
* ( ypixels
+ i
),
186 bitmap
->buffer
+ pitch
* i
, len
);
190 FT_Int len
= ( width
* bpp
+ 7 ) >> 3;
193 for ( i
= 0; i
< bitmap
->rows
; i
++ )
194 FT_MEM_COPY( buffer
+ new_pitch
* i
,
195 bitmap
->buffer
+ pitch
* i
, len
);
198 FT_FREE( bitmap
->buffer
);
199 bitmap
->buffer
= buffer
;
201 if ( bitmap
->pitch
< 0 )
202 new_pitch
= -new_pitch
;
204 /* set pitch only, width and height are left untouched */
205 bitmap
->pitch
= new_pitch
;
211 /* documentation is in ftbitmap.h */
213 FT_EXPORT_DEF( FT_Error
)
214 FT_Bitmap_Embolden( FT_Library library
,
221 FT_Int i
, x
, y
, pitch
;
226 return FT_Err_Invalid_Library_Handle
;
228 if ( !bitmap
|| !bitmap
->buffer
)
229 return FT_Err_Invalid_Argument
;
231 xstr
= FT_PIX_ROUND( xStrength
) >> 6;
232 ystr
= FT_PIX_ROUND( yStrength
) >> 6;
234 if ( xstr
== 0 && ystr
== 0 )
236 else if ( xstr
< 0 || ystr
< 0 )
237 return FT_Err_Invalid_Argument
;
239 switch ( bitmap
->pixel_mode
)
241 case FT_PIXEL_MODE_GRAY2
:
242 case FT_PIXEL_MODE_GRAY4
:
248 if ( bitmap
->pixel_mode
== FT_PIXEL_MODE_GRAY2
)
249 align
= ( bitmap
->width
+ xstr
+ 3 ) / 4;
251 align
= ( bitmap
->width
+ xstr
+ 1 ) / 2;
253 FT_Bitmap_New( &tmp
);
255 error
= FT_Bitmap_Convert( library
, bitmap
, &tmp
, align
);
259 FT_Bitmap_Done( library
, bitmap
);
264 case FT_PIXEL_MODE_MONO
:
269 case FT_PIXEL_MODE_LCD
:
273 case FT_PIXEL_MODE_LCD_V
:
278 error
= ft_bitmap_assure_buffer( library
->memory
, bitmap
, xstr
, ystr
);
282 pitch
= bitmap
->pitch
;
284 p
= bitmap
->buffer
+ pitch
* ystr
;
288 p
= bitmap
->buffer
+ pitch
* ( bitmap
->rows
- 1 );
292 for ( y
= 0; y
< bitmap
->rows
; y
++ )
297 * From the last pixel on, make each pixel or'ed with the
298 * `xstr' pixels before it.
300 for ( x
= pitch
- 1; x
>= 0; x
-- )
306 for ( i
= 1; i
<= xstr
; i
++ )
308 if ( bitmap
->pixel_mode
== FT_PIXEL_MODE_MONO
)
312 /* the maximum value of 8 for `xstr' comes from here */
314 p
[x
] |= p
[x
- 1] << ( 8 - i
);
325 if ( p
[x
] + p
[x
- i
] > bitmap
->num_grays
- 1 )
327 p
[x
] = (unsigned char)(bitmap
->num_grays
- 1);
332 p
[x
] = (unsigned char)(p
[x
] + p
[x
-i
]);
333 if ( p
[x
] == bitmap
->num_grays
- 1 )
346 * Make the above `ystr' rows or'ed with it.
348 for ( x
= 1; x
<= ystr
; x
++ )
353 q
= p
- bitmap
->pitch
* x
;
354 for ( i
= 0; i
< pitch
; i
++ )
361 bitmap
->width
+= xstr
;
362 bitmap
->rows
+= ystr
;
368 /* documentation is in ftbitmap.h */
370 FT_EXPORT_DEF( FT_Error
)
371 FT_Bitmap_Convert( FT_Library library
,
372 const FT_Bitmap
*source
,
376 FT_Error error
= FT_Err_Ok
;
381 return FT_Err_Invalid_Library_Handle
;
383 memory
= library
->memory
;
385 switch ( source
->pixel_mode
)
387 case FT_PIXEL_MODE_MONO
:
388 case FT_PIXEL_MODE_GRAY
:
389 case FT_PIXEL_MODE_GRAY2
:
390 case FT_PIXEL_MODE_GRAY4
:
396 old_size
= target
->rows
* target
->pitch
;
398 old_size
= -old_size
;
400 target
->pixel_mode
= FT_PIXEL_MODE_GRAY
;
401 target
->rows
= source
->rows
;
402 target
->width
= source
->width
;
407 pad
= source
->width
% alignment
;
409 pad
= alignment
- pad
;
412 target
->pitch
= source
->width
+ pad
;
414 if ( target
->rows
* target
->pitch
> old_size
&&
415 FT_QREALLOC( target
->buffer
,
416 old_size
, target
->rows
* target
->pitch
) )
422 error
= FT_Err_Invalid_Argument
;
425 switch ( source
->pixel_mode
)
427 case FT_PIXEL_MODE_MONO
:
429 FT_Byte
* s
= source
->buffer
;
430 FT_Byte
* t
= target
->buffer
;
434 target
->num_grays
= 2;
436 for ( i
= source
->rows
; i
> 0; i
-- )
443 /* get the full bytes */
444 for ( j
= source
->width
>> 3; j
> 0; j
-- )
446 FT_Int val
= ss
[0]; /* avoid a byte->int cast on each line */
449 tt
[0] = (FT_Byte
)( ( val
& 0x80 ) >> 7 );
450 tt
[1] = (FT_Byte
)( ( val
& 0x40 ) >> 6 );
451 tt
[2] = (FT_Byte
)( ( val
& 0x20 ) >> 5 );
452 tt
[3] = (FT_Byte
)( ( val
& 0x10 ) >> 4 );
453 tt
[4] = (FT_Byte
)( ( val
& 0x08 ) >> 3 );
454 tt
[5] = (FT_Byte
)( ( val
& 0x04 ) >> 2 );
455 tt
[6] = (FT_Byte
)( ( val
& 0x02 ) >> 1 );
456 tt
[7] = (FT_Byte
)( val
& 0x01 );
462 /* get remaining pixels (if any) */
463 j
= source
->width
& 7;
471 tt
[0] = (FT_Byte
)( ( val
& 0x80 ) >> 7);
484 case FT_PIXEL_MODE_GRAY
:
486 FT_Int width
= source
->width
;
487 FT_Byte
* s
= source
->buffer
;
488 FT_Byte
* t
= target
->buffer
;
489 FT_Int s_pitch
= source
->pitch
;
490 FT_Int t_pitch
= target
->pitch
;
494 target
->num_grays
= 256;
496 for ( i
= source
->rows
; i
> 0; i
-- )
498 FT_ARRAY_COPY( t
, s
, width
);
507 case FT_PIXEL_MODE_GRAY2
:
509 FT_Byte
* s
= source
->buffer
;
510 FT_Byte
* t
= target
->buffer
;
514 target
->num_grays
= 4;
516 for ( i
= source
->rows
; i
> 0; i
-- )
523 /* get the full bytes */
524 for ( j
= source
->width
>> 2; j
> 0; j
-- )
529 tt
[0] = (FT_Byte
)( ( val
& 0xC0 ) >> 6 );
530 tt
[1] = (FT_Byte
)( ( val
& 0x30 ) >> 4 );
531 tt
[2] = (FT_Byte
)( ( val
& 0x0C ) >> 2 );
532 tt
[3] = (FT_Byte
)( ( val
& 0x03 ) );
538 j
= source
->width
& 3;
546 tt
[0] = (FT_Byte
)( ( val
& 0xC0 ) >> 6 );
559 case FT_PIXEL_MODE_GRAY4
:
561 FT_Byte
* s
= source
->buffer
;
562 FT_Byte
* t
= target
->buffer
;
566 target
->num_grays
= 16;
568 for ( i
= source
->rows
; i
> 0; i
-- )
575 /* get the full bytes */
576 for ( j
= source
->width
>> 1; j
> 0; j
-- )
581 tt
[0] = (FT_Byte
)( ( val
& 0xF0 ) >> 4 );
582 tt
[1] = (FT_Byte
)( ( val
& 0x0F ) );
588 if ( source
->width
& 1 )
589 tt
[0] = (FT_Byte
)( ( ss
[0] & 0xF0 ) >> 4 );
606 /* documentation is in ftbitmap.h */
608 FT_EXPORT_DEF( FT_Error
)
609 FT_Bitmap_Done( FT_Library library
,
616 return FT_Err_Invalid_Library_Handle
;
619 return FT_Err_Invalid_Argument
;
621 memory
= library
->memory
;
623 FT_FREE( bitmap
->buffer
);
624 *bitmap
= null_bitmap
;