1 /****************************************************************************
5 * FreeType utility functions for bitmaps (body).
7 * Copyright (C) 2004-2023 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.
19 #include <freetype/internal/ftdebug.h>
21 #include <freetype/ftbitmap.h>
22 #include <freetype/ftimage.h>
23 #include <freetype/internal/ftobjs.h>
26 /**************************************************************************
28 * The macro FT_COMPONENT is used in trace mode. It is an implicit
29 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
30 * messages during execution.
33 #define FT_COMPONENT bitmap
37 const FT_Bitmap null_bitmap = { 0, 0, 0, NULL, 0, 0, 0, NULL };
40 /* documentation is in ftbitmap.h */
43 FT_Bitmap_Init( FT_Bitmap *abitmap )
46 *abitmap = null_bitmap;
50 /* deprecated function name; retained for ABI compatibility */
53 FT_Bitmap_New( FT_Bitmap *abitmap )
56 *abitmap = null_bitmap;
60 /* documentation is in ftbitmap.h */
62 FT_EXPORT_DEF( FT_Error )
63 FT_Bitmap_Copy( FT_Library library,
64 const FT_Bitmap *source,
68 FT_Error error = FT_Err_Ok;
74 return FT_THROW( Invalid_Library_Handle );
76 if ( !source || !target )
77 return FT_THROW( Invalid_Argument );
79 if ( source == target )
82 flip = ( source->pitch < 0 && target->pitch > 0 ) ||
83 ( source->pitch > 0 && target->pitch < 0 );
85 memory = library->memory;
86 FT_FREE( target->buffer );
91 target->pitch = -target->pitch;
93 if ( !source->buffer )
96 pitch = source->pitch;
100 FT_MEM_QALLOC_MULT( target->buffer, target->rows, pitch );
106 /* take care of bitmap flow */
108 FT_Byte* s = source->buffer;
109 FT_Byte* t = target->buffer;
112 t += (FT_ULong)pitch * ( target->rows - 1 );
114 for ( i = target->rows; i > 0; i-- )
116 FT_ARRAY_COPY( t, s, pitch );
123 FT_MEM_COPY( target->buffer, source->buffer,
124 (FT_Long)source->rows * pitch );
131 /* Enlarge `bitmap' horizontally and vertically by `xpixels' */
132 /* and `ypixels', respectively. */
135 ft_bitmap_assure_buffer( FT_Memory memory,
142 unsigned int new_pitch;
144 FT_UInt width, height;
145 unsigned char* buffer = NULL;
148 width = bitmap->width;
149 height = bitmap->rows;
150 pitch = (unsigned int)FT_ABS( bitmap->pitch );
152 switch ( bitmap->pixel_mode )
154 case FT_PIXEL_MODE_MONO:
156 new_pitch = ( width + xpixels + 7 ) >> 3;
158 case FT_PIXEL_MODE_GRAY2:
160 new_pitch = ( width + xpixels + 3 ) >> 2;
162 case FT_PIXEL_MODE_GRAY4:
164 new_pitch = ( width + xpixels + 1 ) >> 1;
166 case FT_PIXEL_MODE_GRAY:
167 case FT_PIXEL_MODE_LCD:
168 case FT_PIXEL_MODE_LCD_V:
170 new_pitch = width + xpixels;
173 return FT_THROW( Invalid_Glyph_Format );
176 /* if no need to allocate memory */
177 if ( ypixels == 0 && new_pitch <= pitch )
179 /* zero the padding */
180 FT_UInt bit_width = pitch * 8;
181 FT_UInt bit_last = ( width + xpixels ) * bpp;
184 if ( bit_last < bit_width )
186 FT_Byte* line = bitmap->buffer + ( bit_last >> 3 );
187 FT_Byte* end = bitmap->buffer + pitch;
188 FT_UInt shift = bit_last & 7;
189 FT_UInt mask = 0xFF00U >> shift;
190 FT_UInt count = height;
193 for ( ; count > 0; count--, line += pitch, end += pitch )
195 FT_Byte* write = line;
200 write[0] = (FT_Byte)( write[0] & mask );
204 FT_MEM_ZERO( write, end - write );
211 /* otherwise allocate new buffer */
212 if ( FT_QALLOC_MULT( buffer, bitmap->rows + ypixels, new_pitch ) )
215 /* new rows get added at the top of the bitmap, */
216 /* thus take care of the flow direction */
217 if ( bitmap->pitch > 0 )
219 FT_UInt len = ( width * bpp + 7 ) >> 3;
221 unsigned char* in = bitmap->buffer;
222 unsigned char* out = buffer;
224 unsigned char* limit = bitmap->buffer + pitch * bitmap->rows;
225 unsigned int delta = new_pitch - len;
228 FT_MEM_ZERO( out, new_pitch * ypixels );
229 out += new_pitch * ypixels;
233 FT_MEM_COPY( out, in, len );
237 /* we use FT_QALLOC_MULT, which doesn't zero out the buffer; */
238 /* consequently, we have to manually zero out the remaining bytes */
239 FT_MEM_ZERO( out, delta );
245 FT_UInt len = ( width * bpp + 7 ) >> 3;
247 unsigned char* in = bitmap->buffer;
248 unsigned char* out = buffer;
250 unsigned char* limit = bitmap->buffer + pitch * bitmap->rows;
251 unsigned int delta = new_pitch - len;
256 FT_MEM_COPY( out, in, len );
260 FT_MEM_ZERO( out, delta );
264 FT_MEM_ZERO( out, new_pitch * ypixels );
267 FT_FREE( bitmap->buffer );
268 bitmap->buffer = buffer;
270 /* set pitch only, width and height are left untouched */
271 if ( bitmap->pitch < 0 )
272 bitmap->pitch = -(int)new_pitch;
274 bitmap->pitch = (int)new_pitch;
280 /* documentation is in ftbitmap.h */
282 FT_EXPORT_DEF( FT_Error )
283 FT_Bitmap_Embolden( FT_Library library,
296 return FT_THROW( Invalid_Library_Handle );
298 if ( !bitmap || !bitmap->buffer )
299 return FT_THROW( Invalid_Argument );
301 if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) ||
302 ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) )
303 return FT_THROW( Invalid_Argument );
305 xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6;
306 ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6;
308 if ( xstr == 0 && ystr == 0 )
310 else if ( xstr < 0 || ystr < 0 )
311 return FT_THROW( Invalid_Argument );
313 switch ( bitmap->pixel_mode )
315 case FT_PIXEL_MODE_GRAY2:
316 case FT_PIXEL_MODE_GRAY4:
321 /* convert to 8bpp */
322 FT_Bitmap_Init( &tmp );
323 error = FT_Bitmap_Convert( library, bitmap, &tmp, 1 );
327 FT_Bitmap_Done( library, bitmap );
332 case FT_PIXEL_MODE_MONO:
337 case FT_PIXEL_MODE_LCD:
341 case FT_PIXEL_MODE_LCD_V:
345 case FT_PIXEL_MODE_BGRA:
346 /* We don't embolden color glyphs. */
350 error = ft_bitmap_assure_buffer( library->memory, bitmap,
351 (FT_UInt)xstr, (FT_UInt)ystr );
355 /* take care of bitmap flow */
356 pitch = bitmap->pitch;
358 p = bitmap->buffer + pitch * ystr;
362 p = bitmap->buffer + (FT_UInt)pitch * ( bitmap->rows - 1 );
366 for ( y = 0; y < bitmap->rows; y++ )
371 * From the last pixel on, make each pixel or'ed with the
372 * `xstr' pixels before it.
374 for ( x = pitch - 1; x >= 0; x-- )
380 for ( i = 1; i <= xstr; i++ )
382 if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO )
386 /* the maximum value of 8 for `xstr' comes from here */
388 p[x] |= p[x - 1] << ( 8 - i );
399 if ( p[x] + p[x - i] > bitmap->num_grays - 1 )
401 p[x] = (unsigned char)( bitmap->num_grays - 1 );
406 p[x] = (unsigned char)( p[x] + p[x - i] );
407 if ( p[x] == bitmap->num_grays - 1 )
420 * Make the above `ystr' rows or'ed with it.
422 for ( x = 1; x <= ystr; x++ )
427 q = p - bitmap->pitch * x;
428 for ( i = 0; i < pitch; i++ )
435 bitmap->width += (FT_UInt)xstr;
436 bitmap->rows += (FT_UInt)ystr;
443 ft_gray_for_premultiplied_srgb_bgra( const FT_Byte* bgra )
449 /* Short-circuit transparent color to avoid division by zero. */
454 * Luminosity for sRGB is defined using ~0.2126,0.7152,0.0722
455 * coefficients for RGB channels *on the linear colors*.
456 * A gamma of 2.2 is fair to assume. And then, we need to
457 * undo the premultiplication too.
459 * http://www.brucelindbloom.com/index.html?WorkingSpaceInfo.html#SideNotes
461 * We do the computation with integers only, applying a gamma of 2.0.
462 * We guarantee 32-bit arithmetic to avoid overflow but the resulting
463 * luminosity fits into 16 bits.
467 l = ( 4731UL /* 0.072186 * 65536 */ * bgra[0] * bgra[0] +
468 46868UL /* 0.715158 * 65536 */ * bgra[1] * bgra[1] +
469 13937UL /* 0.212656 * 65536 */ * bgra[2] * bgra[2] ) >> 16;
472 * Final transparency can be determined as follows.
474 * - If alpha is zero, we want 0.
475 * - If alpha is zero and luminosity is zero, we want 255.
476 * - If alpha is zero and luminosity is one, we want 0.
478 * So the formula is a * (1 - l) = a - l * a.
480 * We still need to undo premultiplication by dividing l by a*a.
484 return (FT_Byte)( a - l / a );
488 /* documentation is in ftbitmap.h */
490 FT_EXPORT_DEF( FT_Error )
491 FT_Bitmap_Convert( FT_Library library,
492 const FT_Bitmap *source,
496 FT_Error error = FT_Err_Ok;
504 return FT_THROW( Invalid_Library_Handle );
506 if ( !source || !target )
507 return FT_THROW( Invalid_Argument );
509 memory = library->memory;
511 switch ( source->pixel_mode )
513 case FT_PIXEL_MODE_MONO:
514 case FT_PIXEL_MODE_GRAY:
515 case FT_PIXEL_MODE_GRAY2:
516 case FT_PIXEL_MODE_GRAY4:
517 case FT_PIXEL_MODE_LCD:
518 case FT_PIXEL_MODE_LCD_V:
519 case FT_PIXEL_MODE_BGRA:
521 FT_Int width = (FT_Int)source->width;
522 FT_Int neg = ( target->pitch == 0 && source->pitch < 0 ) ||
526 FT_Bitmap_Done( library, target );
528 target->pixel_mode = FT_PIXEL_MODE_GRAY;
529 target->rows = source->rows;
530 target->width = source->width;
534 FT_Int rem = width % alignment;
538 width = alignment > 0 ? width - rem + alignment
539 : width - rem - alignment;
542 if ( FT_QALLOC_MULT( target->buffer, target->rows, width ) )
545 target->pitch = neg ? -width : width;
550 error = FT_THROW( Invalid_Argument );
556 /* take care of bitmap flow */
557 if ( source->pitch < 0 )
558 s -= source->pitch * (FT_Int)( source->rows - 1 );
559 if ( target->pitch < 0 )
560 t -= target->pitch * (FT_Int)( target->rows - 1 );
562 switch ( source->pixel_mode )
564 case FT_PIXEL_MODE_MONO:
569 target->num_grays = 2;
571 for ( i = source->rows; i > 0; i-- )
578 /* get the full bytes */
579 for ( j = source->width >> 3; j > 0; j-- )
581 FT_Int val = ss[0]; /* avoid a byte->int cast on each line */
584 tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 );
585 tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 );
586 tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 );
587 tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 );
588 tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 );
589 tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 );
590 tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 );
591 tt[7] = (FT_Byte)( val & 0x01 );
597 /* get remaining pixels (if any) */
598 j = source->width & 7;
606 tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7);
619 case FT_PIXEL_MODE_GRAY:
620 case FT_PIXEL_MODE_LCD:
621 case FT_PIXEL_MODE_LCD_V:
623 FT_UInt width = source->width;
627 target->num_grays = 256;
629 for ( i = source->rows; i > 0; i-- )
631 FT_ARRAY_COPY( t, s, width );
640 case FT_PIXEL_MODE_GRAY2:
645 target->num_grays = 4;
647 for ( i = source->rows; i > 0; i-- )
654 /* get the full bytes */
655 for ( j = source->width >> 2; j > 0; j-- )
660 tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
661 tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 );
662 tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 );
663 tt[3] = (FT_Byte)( ( val & 0x03 ) );
669 j = source->width & 3;
677 tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
690 case FT_PIXEL_MODE_GRAY4:
695 target->num_grays = 16;
697 for ( i = source->rows; i > 0; i-- )
704 /* get the full bytes */
705 for ( j = source->width >> 1; j > 0; j-- )
710 tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 );
711 tt[1] = (FT_Byte)( ( val & 0x0F ) );
717 if ( source->width & 1 )
718 tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 );
727 case FT_PIXEL_MODE_BGRA:
732 target->num_grays = 256;
734 for ( i = source->rows; i > 0; i-- )
741 for ( j = source->width; j > 0; j-- )
743 tt[0] = ft_gray_for_premultiplied_srgb_bgra( ss );
763 /* documentation is in ftbitmap.h */
765 FT_EXPORT_DEF( FT_Error )
766 FT_Bitmap_Blend( FT_Library library,
767 const FT_Bitmap* source_,
768 const FT_Vector source_offset_,
770 FT_Vector *atarget_offset,
773 FT_Error error = FT_Err_Ok;
776 FT_Bitmap source_bitmap;
777 const FT_Bitmap* source;
779 FT_Vector source_offset;
780 FT_Vector target_offset;
782 FT_Bool free_source_bitmap = 0;
783 FT_Bool free_target_bitmap_on_error = 0;
785 FT_Pos source_llx, source_lly, source_urx, source_ury;
786 FT_Pos target_llx, target_lly, target_urx, target_ury;
787 FT_Pos final_llx, final_lly, final_urx, final_ury;
789 unsigned int final_rows, final_width;
793 if ( !library || !target || !source_ || !atarget_offset )
794 return FT_THROW( Invalid_Argument );
796 memory = library->memory;
798 if ( !( target->pixel_mode == FT_PIXEL_MODE_NONE ||
799 ( target->pixel_mode == FT_PIXEL_MODE_BGRA &&
801 return FT_THROW( Invalid_Argument );
803 if ( source_->pixel_mode == FT_PIXEL_MODE_NONE )
804 return FT_Err_Ok; /* nothing to do */
806 /* pitches must have the same sign */
807 if ( target->pixel_mode == FT_PIXEL_MODE_BGRA &&
808 ( source_->pitch ^ target->pitch ) < 0 )
809 return FT_THROW( Invalid_Argument );
811 if ( !( source_->width && source_->rows ) )
812 return FT_Err_Ok; /* nothing to do */
814 /* assure integer pixel offsets */
815 source_offset.x = FT_PIX_FLOOR( source_offset_.x );
816 source_offset.y = FT_PIX_FLOOR( source_offset_.y );
817 target_offset.x = FT_PIX_FLOOR( atarget_offset->x );
818 target_offset.y = FT_PIX_FLOOR( atarget_offset->y );
820 /* get source bitmap dimensions */
821 source_llx = source_offset.x;
822 if ( FT_LONG_MIN + (FT_Pos)( source_->rows << 6 ) + 64 > source_offset.y )
825 "FT_Bitmap_Blend: y coordinate overflow in source bitmap\n" ));
826 return FT_THROW( Invalid_Argument );
828 source_lly = source_offset.y - ( source_->rows << 6 );
830 if ( FT_LONG_MAX - (FT_Pos)( source_->width << 6 ) - 64 < source_llx )
833 "FT_Bitmap_Blend: x coordinate overflow in source bitmap\n" ));
834 return FT_THROW( Invalid_Argument );
836 source_urx = source_llx + ( source_->width << 6 );
837 source_ury = source_offset.y;
839 /* get target bitmap dimensions */
840 if ( target->width && target->rows )
842 target_llx = target_offset.x;
843 if ( FT_LONG_MIN + (FT_Pos)( target->rows << 6 ) > target_offset.y )
846 "FT_Bitmap_Blend: y coordinate overflow in target bitmap\n" ));
847 return FT_THROW( Invalid_Argument );
849 target_lly = target_offset.y - ( target->rows << 6 );
851 if ( FT_LONG_MAX - (FT_Pos)( target->width << 6 ) < target_llx )
854 "FT_Bitmap_Blend: x coordinate overflow in target bitmap\n" ));
855 return FT_THROW( Invalid_Argument );
857 target_urx = target_llx + ( target->width << 6 );
858 target_ury = target_offset.y;
862 target_llx = FT_LONG_MAX;
863 target_lly = FT_LONG_MAX;
864 target_urx = FT_LONG_MIN;
865 target_ury = FT_LONG_MIN;
868 /* compute final bitmap dimensions */
869 final_llx = FT_MIN( source_llx, target_llx );
870 final_lly = FT_MIN( source_lly, target_lly );
871 final_urx = FT_MAX( source_urx, target_urx );
872 final_ury = FT_MAX( source_ury, target_ury );
874 final_width = ( final_urx - final_llx ) >> 6;
875 final_rows = ( final_ury - final_lly ) >> 6;
877 #ifdef FT_DEBUG_LEVEL_TRACE
878 FT_TRACE5(( "FT_Bitmap_Blend:\n" ));
879 FT_TRACE5(( " source bitmap: (%ld, %ld) -- (%ld, %ld); %d x %d\n",
880 source_llx / 64, source_lly / 64,
881 source_urx / 64, source_ury / 64,
882 source_->width, source_->rows ));
884 if ( target->width && target->rows )
885 FT_TRACE5(( " target bitmap: (%ld, %ld) -- (%ld, %ld); %d x %d\n",
886 target_llx / 64, target_lly / 64,
887 target_urx / 64, target_ury / 64,
888 target->width, target->rows ));
890 FT_TRACE5(( " target bitmap: empty\n" ));
892 if ( final_width && final_rows )
893 FT_TRACE5(( " final bitmap: (%ld, %ld) -- (%ld, %ld); %d x %d\n",
894 final_llx / 64, final_lly / 64,
895 final_urx / 64, final_ury / 64,
896 final_width, final_rows ));
898 FT_TRACE5(( " final bitmap: empty\n" ));
899 #endif /* FT_DEBUG_LEVEL_TRACE */
901 if ( !( final_width && final_rows ) )
902 return FT_Err_Ok; /* nothing to do */
904 /* for blending, set offset vector of final bitmap */
905 /* temporarily to (0,0) */
906 source_llx -= final_llx;
907 source_lly -= final_lly;
909 if ( target->width && target->rows )
911 target_llx -= final_llx;
912 target_lly -= final_lly;
915 /* set up target bitmap */
916 if ( target->pixel_mode == FT_PIXEL_MODE_NONE )
918 /* create new empty bitmap */
919 target->width = final_width;
920 target->rows = final_rows;
921 target->pixel_mode = FT_PIXEL_MODE_BGRA;
922 target->pitch = (int)final_width * 4;
923 target->num_grays = 256;
925 if ( FT_LONG_MAX / target->pitch < (int)target->rows )
927 FT_TRACE5(( "FT_Blend_Bitmap: target bitmap too large (%d x %d)\n",
928 final_width, final_rows ));
929 return FT_THROW( Invalid_Argument );
932 if ( FT_ALLOC( target->buffer, target->pitch * (int)target->rows ) )
935 free_target_bitmap_on_error = 1;
937 else if ( target->width != final_width ||
938 target->rows != final_rows )
940 /* adjust old bitmap to enlarged size */
941 int pitch, new_pitch;
943 unsigned char* buffer = NULL;
946 pitch = target->pitch;
951 new_pitch = (int)final_width * 4;
953 if ( FT_LONG_MAX / new_pitch < (int)final_rows )
955 FT_TRACE5(( "FT_Blend_Bitmap: target bitmap too large (%d x %d)\n",
956 final_width, final_rows ));
957 return FT_THROW( Invalid_Argument );
960 /* TODO: provide an in-buffer solution for large bitmaps */
961 /* to avoid allocation of a new buffer */
962 if ( FT_ALLOC( buffer, new_pitch * (int)final_rows ) )
965 /* copy data to new buffer */
969 /* the bitmap flow is from top to bottom, */
970 /* but y is measured from bottom to top */
971 if ( target->pitch < 0 )
981 ( final_rows - y - target->rows ) * new_pitch +
983 unsigned char* limit_p =
984 p + pitch * (int)target->rows;
987 while ( p < limit_p )
989 FT_MEM_COPY( q, p, pitch );
996 FT_FREE( target->buffer );
998 target->width = final_width;
999 target->rows = final_rows;
1001 if ( target->pitch < 0 )
1002 target->pitch = -new_pitch;
1004 target->pitch = new_pitch;
1006 target->buffer = buffer;
1009 /* adjust source bitmap if necessary */
1010 if ( source_->pixel_mode != FT_PIXEL_MODE_GRAY )
1012 FT_Bitmap_Init( &source_bitmap );
1013 error = FT_Bitmap_Convert( library, source_, &source_bitmap, 1 );
1017 source = &source_bitmap;
1018 free_source_bitmap = 1;
1023 /* do blending; the code below returns pre-multiplied channels, */
1024 /* similar to what FreeType gets from `CBDT' tables */
1025 x = source_llx >> 6;
1026 y = source_lly >> 6;
1028 /* the bitmap flow is from top to bottom, */
1029 /* but y is measured from bottom to top */
1030 if ( target->pitch < 0 )
1040 ( target->rows - y - source->rows ) * target->pitch +
1042 unsigned char* limit_p =
1043 p + source->pitch * (int)source->rows;
1046 while ( p < limit_p )
1048 unsigned char* r = p;
1049 unsigned char* s = q;
1050 unsigned char* limit_r = r + source->width;
1053 while ( r < limit_r )
1056 int fa = color.alpha * aa / 255;
1058 int fb = color.blue * fa / 255;
1059 int fg = color.green * fa / 255;
1060 int fr = color.red * fa / 255;
1070 *s++ = (unsigned char)( bb * ba2 / 255 + fb );
1071 *s++ = (unsigned char)( bg * ba2 / 255 + fg );
1072 *s++ = (unsigned char)( br * ba2 / 255 + fr );
1073 *s++ = (unsigned char)( ba * ba2 / 255 + fa );
1081 atarget_offset->x = final_llx;
1082 atarget_offset->y = final_lly + ( final_rows << 6 );
1085 if ( error && free_target_bitmap_on_error )
1086 FT_Bitmap_Done( library, target );
1088 if ( free_source_bitmap )
1089 FT_Bitmap_Done( library, &source_bitmap );
1095 /* documentation is in ftbitmap.h */
1097 FT_EXPORT_DEF( FT_Error )
1098 FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot )
1100 if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP &&
1101 !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
1107 FT_Bitmap_Init( &bitmap );
1108 error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap );
1112 slot->bitmap = bitmap;
1113 slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
1120 /* documentation is in ftbitmap.h */
1122 FT_EXPORT_DEF( FT_Error )
1123 FT_Bitmap_Done( FT_Library library,
1130 return FT_THROW( Invalid_Library_Handle );
1133 return FT_THROW( Invalid_Argument );
1135 memory = library->memory;
1137 FT_FREE( bitmap->buffer );
1138 *bitmap = null_bitmap;