Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  ftbitmap.c                                                             */
  4. /*                                                                         */
  5. /*    FreeType utility functions for bitmaps (body).                       */
  6. /*                                                                         */
  7. /*  Copyright 2004-2009, 2011, 2013 by                                     */
  8. /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  9. /*                                                                         */
  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.                                        */
  15. /*                                                                         */
  16. /***************************************************************************/
  17.  
  18.  
  19. #include <ft2build.h>
  20. #include FT_INTERNAL_DEBUG_H
  21.  
  22. #include FT_BITMAP_H
  23. #include FT_IMAGE_H
  24. #include FT_INTERNAL_OBJECTS_H
  25.  
  26.  
  27.   static
  28.   const FT_Bitmap  null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 };
  29.  
  30.  
  31.   /* documentation is in ftbitmap.h */
  32.  
  33.   FT_EXPORT_DEF( void )
  34.   FT_Bitmap_New( FT_Bitmap  *abitmap )
  35.   {
  36.     *abitmap = null_bitmap;
  37.   }
  38.  
  39.  
  40.   /* documentation is in ftbitmap.h */
  41.  
  42.   FT_EXPORT_DEF( FT_Error )
  43.   FT_Bitmap_Copy( FT_Library        library,
  44.                   const FT_Bitmap  *source,
  45.                   FT_Bitmap        *target)
  46.   {
  47.     FT_Memory  memory = library->memory;
  48.     FT_Error   error  = FT_Err_Ok;
  49.     FT_Int     pitch  = source->pitch;
  50.     FT_ULong   size;
  51.  
  52.  
  53.     if ( source == target )
  54.       return FT_Err_Ok;
  55.  
  56.     if ( source->buffer == NULL )
  57.     {
  58.       *target = *source;
  59.  
  60.       return FT_Err_Ok;
  61.     }
  62.  
  63.     if ( pitch < 0 )
  64.       pitch = -pitch;
  65.     size = (FT_ULong)( pitch * source->rows );
  66.  
  67.     if ( target->buffer )
  68.     {
  69.       FT_Int    target_pitch = target->pitch;
  70.       FT_ULong  target_size;
  71.  
  72.  
  73.       if ( target_pitch < 0  )
  74.         target_pitch = -target_pitch;
  75.       target_size = (FT_ULong)( target_pitch * target->rows );
  76.  
  77.       if ( target_size != size )
  78.         (void)FT_QREALLOC( target->buffer, target_size, size );
  79.     }
  80.     else
  81.       (void)FT_QALLOC( target->buffer, size );
  82.  
  83.     if ( !error )
  84.     {
  85.       unsigned char *p;
  86.  
  87.  
  88.       p = target->buffer;
  89.       *target = *source;
  90.       target->buffer = p;
  91.  
  92.       FT_MEM_COPY( target->buffer, source->buffer, size );
  93.     }
  94.  
  95.     return error;
  96.   }
  97.  
  98.  
  99.   static FT_Error
  100.   ft_bitmap_assure_buffer( FT_Memory   memory,
  101.                            FT_Bitmap*  bitmap,
  102.                            FT_UInt     xpixels,
  103.                            FT_UInt     ypixels )
  104.   {
  105.     FT_Error        error;
  106.     int             pitch;
  107.     int             new_pitch;
  108.     FT_UInt         bpp;
  109.     FT_Int          i, width, height;
  110.     unsigned char*  buffer = NULL;
  111.  
  112.  
  113.     width  = bitmap->width;
  114.     height = bitmap->rows;
  115.     pitch  = bitmap->pitch;
  116.     if ( pitch < 0 )
  117.       pitch = -pitch;
  118.  
  119.     switch ( bitmap->pixel_mode )
  120.     {
  121.     case FT_PIXEL_MODE_MONO:
  122.       bpp       = 1;
  123.       new_pitch = ( width + xpixels + 7 ) >> 3;
  124.       break;
  125.     case FT_PIXEL_MODE_GRAY2:
  126.       bpp       = 2;
  127.       new_pitch = ( width + xpixels + 3 ) >> 2;
  128.       break;
  129.     case FT_PIXEL_MODE_GRAY4:
  130.       bpp       = 4;
  131.       new_pitch = ( width + xpixels + 1 ) >> 1;
  132.       break;
  133.     case FT_PIXEL_MODE_GRAY:
  134.     case FT_PIXEL_MODE_LCD:
  135.     case FT_PIXEL_MODE_LCD_V:
  136.       bpp       = 8;
  137.       new_pitch = ( width + xpixels );
  138.       break;
  139.     default:
  140.       return FT_THROW( Invalid_Glyph_Format );
  141.     }
  142.  
  143.     /* if no need to allocate memory */
  144.     if ( ypixels == 0 && new_pitch <= pitch )
  145.     {
  146.       /* zero the padding */
  147.       FT_Int  bit_width = pitch * 8;
  148.       FT_Int  bit_last  = ( width + xpixels ) * bpp;
  149.  
  150.  
  151.       if ( bit_last < bit_width )
  152.       {
  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;
  158.  
  159.  
  160.         for ( ; count > 0; count--, line += pitch, end += pitch )
  161.         {
  162.           FT_Byte*  write = line;
  163.  
  164.  
  165.           if ( shift > 0 )
  166.           {
  167.             write[0] = (FT_Byte)( write[0] & mask );
  168.             write++;
  169.           }
  170.           if ( write < end )
  171.             FT_MEM_ZERO( write, end-write );
  172.         }
  173.       }
  174.  
  175.       return FT_Err_Ok;
  176.     }
  177.  
  178.     if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) )
  179.       return error;
  180.  
  181.     if ( bitmap->pitch > 0 )
  182.     {
  183.       FT_Int  len = ( width * bpp + 7 ) >> 3;
  184.  
  185.  
  186.       for ( i = 0; i < bitmap->rows; i++ )
  187.         FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ),
  188.                      bitmap->buffer + pitch * i, len );
  189.     }
  190.     else
  191.     {
  192.       FT_Int  len = ( width * bpp + 7 ) >> 3;
  193.  
  194.  
  195.       for ( i = 0; i < bitmap->rows; i++ )
  196.         FT_MEM_COPY( buffer + new_pitch * i,
  197.                      bitmap->buffer + pitch * i, len );
  198.     }
  199.  
  200.     FT_FREE( bitmap->buffer );
  201.     bitmap->buffer = buffer;
  202.  
  203.     if ( bitmap->pitch < 0 )
  204.       new_pitch = -new_pitch;
  205.  
  206.     /* set pitch only, width and height are left untouched */
  207.     bitmap->pitch = new_pitch;
  208.  
  209.     return FT_Err_Ok;
  210.   }
  211.  
  212.  
  213.   /* documentation is in ftbitmap.h */
  214.  
  215.   FT_EXPORT_DEF( FT_Error )
  216.   FT_Bitmap_Embolden( FT_Library  library,
  217.                       FT_Bitmap*  bitmap,
  218.                       FT_Pos      xStrength,
  219.                       FT_Pos      yStrength )
  220.   {
  221.     FT_Error        error;
  222.     unsigned char*  p;
  223.     FT_Int          i, x, y, pitch;
  224.     FT_Int          xstr, ystr;
  225.  
  226.  
  227.     if ( !library )
  228.       return FT_THROW( Invalid_Library_Handle );
  229.  
  230.     if ( !bitmap || !bitmap->buffer )
  231.       return FT_THROW( Invalid_Argument );
  232.  
  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 );
  236.  
  237.     xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6;
  238.     ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6;
  239.  
  240.     if ( xstr == 0 && ystr == 0 )
  241.       return FT_Err_Ok;
  242.     else if ( xstr < 0 || ystr < 0 )
  243.       return FT_THROW( Invalid_Argument );
  244.  
  245.     switch ( bitmap->pixel_mode )
  246.     {
  247.     case FT_PIXEL_MODE_GRAY2:
  248.     case FT_PIXEL_MODE_GRAY4:
  249.       {
  250.         FT_Bitmap  tmp;
  251.         FT_Int     align;
  252.  
  253.  
  254.         if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 )
  255.           align = ( bitmap->width + xstr + 3 ) / 4;
  256.         else
  257.           align = ( bitmap->width + xstr + 1 ) / 2;
  258.  
  259.         FT_Bitmap_New( &tmp );
  260.  
  261.         error = FT_Bitmap_Convert( library, bitmap, &tmp, align );
  262.         if ( error )
  263.           return error;
  264.  
  265.         FT_Bitmap_Done( library, bitmap );
  266.         *bitmap = tmp;
  267.       }
  268.       break;
  269.  
  270.     case FT_PIXEL_MODE_MONO:
  271.       if ( xstr > 8 )
  272.         xstr = 8;
  273.       break;
  274.  
  275.     case FT_PIXEL_MODE_LCD:
  276.       xstr *= 3;
  277.       break;
  278.  
  279.     case FT_PIXEL_MODE_LCD_V:
  280.       ystr *= 3;
  281.       break;
  282.  
  283.     case FT_PIXEL_MODE_BGRA:
  284.       /* We don't embolden color glyphs. */
  285.       return FT_Err_Ok;
  286.     }
  287.  
  288.     error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr );
  289.     if ( error )
  290.       return error;
  291.  
  292.     pitch = bitmap->pitch;
  293.     if ( pitch > 0 )
  294.       p = bitmap->buffer + pitch * ystr;
  295.     else
  296.     {
  297.       pitch = -pitch;
  298.       p = bitmap->buffer + pitch * ( bitmap->rows - 1 );
  299.     }
  300.  
  301.     /* for each row */
  302.     for ( y = 0; y < bitmap->rows ; y++ )
  303.     {
  304.       /*
  305.        * Horizontally:
  306.        *
  307.        * From the last pixel on, make each pixel or'ed with the
  308.        * `xstr' pixels before it.
  309.        */
  310.       for ( x = pitch - 1; x >= 0; x-- )
  311.       {
  312.         unsigned char tmp;
  313.  
  314.  
  315.         tmp = p[x];
  316.         for ( i = 1; i <= xstr; i++ )
  317.         {
  318.           if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO )
  319.           {
  320.             p[x] |= tmp >> i;
  321.  
  322.             /* the maximum value of 8 for `xstr' comes from here */
  323.             if ( x > 0 )
  324.               p[x] |= p[x - 1] << ( 8 - i );
  325.  
  326. #if 0
  327.             if ( p[x] == 0xff )
  328.               break;
  329. #endif
  330.           }
  331.           else
  332.           {
  333.             if ( x - i >= 0 )
  334.             {
  335.               if ( p[x] + p[x - i] > bitmap->num_grays - 1 )
  336.               {
  337.                 p[x] = (unsigned char)(bitmap->num_grays - 1);
  338.                 break;
  339.               }
  340.               else
  341.               {
  342.                 p[x] = (unsigned char)(p[x] + p[x-i]);
  343.                 if ( p[x] == bitmap->num_grays - 1 )
  344.                   break;
  345.               }
  346.             }
  347.             else
  348.               break;
  349.           }
  350.         }
  351.       }
  352.  
  353.       /*
  354.        * Vertically:
  355.        *
  356.        * Make the above `ystr' rows or'ed with it.
  357.        */
  358.       for ( x = 1; x <= ystr; x++ )
  359.       {
  360.         unsigned char*  q;
  361.  
  362.  
  363.         q = p - bitmap->pitch * x;
  364.         for ( i = 0; i < pitch; i++ )
  365.           q[i] |= p[i];
  366.       }
  367.  
  368.       p += bitmap->pitch;
  369.     }
  370.  
  371.     bitmap->width += xstr;
  372.     bitmap->rows += ystr;
  373.  
  374.     return FT_Err_Ok;
  375.   }
  376.  
  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.  
  431.   /* documentation is in ftbitmap.h */
  432.  
  433.   FT_EXPORT_DEF( FT_Error )
  434.   FT_Bitmap_Convert( FT_Library        library,
  435.                      const FT_Bitmap  *source,
  436.                      FT_Bitmap        *target,
  437.                      FT_Int            alignment )
  438.   {
  439.     FT_Error   error = FT_Err_Ok;
  440.     FT_Memory  memory;
  441.  
  442.  
  443.     if ( !library )
  444.       return FT_THROW( Invalid_Library_Handle );
  445.  
  446.     memory = library->memory;
  447.  
  448.     switch ( source->pixel_mode )
  449.     {
  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:
  457.       {
  458.         FT_Int   pad;
  459.         FT_Long  old_size;
  460.  
  461.  
  462.         old_size = target->rows * target->pitch;
  463.         if ( old_size < 0 )
  464.           old_size = -old_size;
  465.  
  466.         target->pixel_mode = FT_PIXEL_MODE_GRAY;
  467.         target->rows       = source->rows;
  468.         target->width      = source->width;
  469.  
  470.         pad = 0;
  471.         if ( alignment > 0 )
  472.         {
  473.           pad = source->width % alignment;
  474.           if ( pad != 0 )
  475.             pad = alignment - pad;
  476.         }
  477.  
  478.         target->pitch = source->width + pad;
  479.  
  480.         if ( target->pitch > 0                                     &&
  481.              (FT_ULong)target->rows > FT_ULONG_MAX / target->pitch )
  482.           return FT_THROW( Invalid_Argument );
  483.  
  484.         if ( target->rows * target->pitch > old_size             &&
  485.              FT_QREALLOC( target->buffer,
  486.                           old_size, target->rows * target->pitch ) )
  487.           return error;
  488.       }
  489.       break;
  490.  
  491.     default:
  492.       error = FT_THROW( Invalid_Argument );
  493.     }
  494.  
  495.     switch ( source->pixel_mode )
  496.     {
  497.     case FT_PIXEL_MODE_MONO:
  498.       {
  499.         FT_Byte*  s = source->buffer;
  500.         FT_Byte*  t = target->buffer;
  501.         FT_Int    i;
  502.  
  503.  
  504.         target->num_grays = 2;
  505.  
  506.         for ( i = source->rows; i > 0; i-- )
  507.         {
  508.           FT_Byte*  ss = s;
  509.           FT_Byte*  tt = t;
  510.           FT_Int    j;
  511.  
  512.  
  513.           /* get the full bytes */
  514.           for ( j = source->width >> 3; j > 0; j-- )
  515.           {
  516.             FT_Int  val = ss[0]; /* avoid a byte->int cast on each line */
  517.  
  518.  
  519.             tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 );
  520.             tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 );
  521.             tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 );
  522.             tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 );
  523.             tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 );
  524.             tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 );
  525.             tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 );
  526.             tt[7] = (FT_Byte)(   val & 0x01 );
  527.  
  528.             tt += 8;
  529.             ss += 1;
  530.           }
  531.  
  532.           /* get remaining pixels (if any) */
  533.           j = source->width & 7;
  534.           if ( j > 0 )
  535.           {
  536.             FT_Int  val = *ss;
  537.  
  538.  
  539.             for ( ; j > 0; j-- )
  540.             {
  541.               tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7);
  542.               val <<= 1;
  543.               tt   += 1;
  544.             }
  545.           }
  546.  
  547.           s += source->pitch;
  548.           t += target->pitch;
  549.         }
  550.       }
  551.       break;
  552.  
  553.  
  554.     case FT_PIXEL_MODE_GRAY:
  555.     case FT_PIXEL_MODE_LCD:
  556.     case FT_PIXEL_MODE_LCD_V:
  557.       {
  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;
  563.         FT_Int    i;
  564.  
  565.  
  566.         target->num_grays = 256;
  567.  
  568.         for ( i = source->rows; i > 0; i-- )
  569.         {
  570.           FT_ARRAY_COPY( t, s, width );
  571.  
  572.           s += s_pitch;
  573.           t += t_pitch;
  574.         }
  575.       }
  576.       break;
  577.  
  578.  
  579.     case FT_PIXEL_MODE_GRAY2:
  580.       {
  581.         FT_Byte*  s = source->buffer;
  582.         FT_Byte*  t = target->buffer;
  583.         FT_Int    i;
  584.  
  585.  
  586.         target->num_grays = 4;
  587.  
  588.         for ( i = source->rows; i > 0; i-- )
  589.         {
  590.           FT_Byte*  ss = s;
  591.           FT_Byte*  tt = t;
  592.           FT_Int    j;
  593.  
  594.  
  595.           /* get the full bytes */
  596.           for ( j = source->width >> 2; j > 0; j-- )
  597.           {
  598.             FT_Int  val = ss[0];
  599.  
  600.  
  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 ) );
  605.  
  606.             ss += 1;
  607.             tt += 4;
  608.           }
  609.  
  610.           j = source->width & 3;
  611.           if ( j > 0 )
  612.           {
  613.             FT_Int  val = ss[0];
  614.  
  615.  
  616.             for ( ; j > 0; j-- )
  617.             {
  618.               tt[0]  = (FT_Byte)( ( val & 0xC0 ) >> 6 );
  619.               val  <<= 2;
  620.               tt    += 1;
  621.             }
  622.           }
  623.  
  624.           s += source->pitch;
  625.           t += target->pitch;
  626.         }
  627.       }
  628.       break;
  629.  
  630.  
  631.     case FT_PIXEL_MODE_GRAY4:
  632.       {
  633.         FT_Byte*  s = source->buffer;
  634.         FT_Byte*  t = target->buffer;
  635.         FT_Int    i;
  636.  
  637.  
  638.         target->num_grays = 16;
  639.  
  640.         for ( i = source->rows; i > 0; i-- )
  641.         {
  642.           FT_Byte*  ss = s;
  643.           FT_Byte*  tt = t;
  644.           FT_Int    j;
  645.  
  646.  
  647.           /* get the full bytes */
  648.           for ( j = source->width >> 1; j > 0; j-- )
  649.           {
  650.             FT_Int  val = ss[0];
  651.  
  652.  
  653.             tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 );
  654.             tt[1] = (FT_Byte)( ( val & 0x0F ) );
  655.  
  656.             ss += 1;
  657.             tt += 2;
  658.           }
  659.  
  660.           if ( source->width & 1 )
  661.             tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 );
  662.  
  663.           s += source->pitch;
  664.           t += target->pitch;
  665.         }
  666.       }
  667.       break;
  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;
  700.  
  701.     default:
  702.       ;
  703.     }
  704.  
  705.     return error;
  706.   }
  707.  
  708.  
  709.   /* documentation is in ftbitmap.h */
  710.  
  711.   FT_EXPORT_DEF( FT_Error )
  712.   FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot  slot )
  713.   {
  714.     if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP   &&
  715.          !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
  716.     {
  717.       FT_Bitmap  bitmap;
  718.       FT_Error   error;
  719.  
  720.  
  721.       FT_Bitmap_New( &bitmap );
  722.       error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap );
  723.       if ( error )
  724.         return error;
  725.  
  726.       slot->bitmap = bitmap;
  727.       slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
  728.     }
  729.  
  730.     return FT_Err_Ok;
  731.   }
  732.  
  733.  
  734.   /* documentation is in ftbitmap.h */
  735.  
  736.   FT_EXPORT_DEF( FT_Error )
  737.   FT_Bitmap_Done( FT_Library  library,
  738.                   FT_Bitmap  *bitmap )
  739.   {
  740.     FT_Memory  memory;
  741.  
  742.  
  743.     if ( !library )
  744.       return FT_THROW( Invalid_Library_Handle );
  745.  
  746.     if ( !bitmap )
  747.       return FT_THROW( Invalid_Argument );
  748.  
  749.     memory = library->memory;
  750.  
  751.     FT_FREE( bitmap->buffer );
  752.     *bitmap = null_bitmap;
  753.  
  754.     return FT_Err_Ok;
  755.   }
  756.  
  757.  
  758. /* END */
  759.