FreeType2 Bitmap to System::Drawing::Bitmap.

Posted by Dennis Roche on Stack Overflow See other posts from Stack Overflow or by Dennis Roche
Published on 2010-05-01T14:43:54Z Indexed on 2010/05/01 14:47 UTC
Read the original article Hit count: 462

Filed under:
|
|
|

Hi,

I'm trying to convert a FreeType2 bitmap to a System::Drawing::Bitmap in C++/CLI. FT_Bitmap has a unsigned char* buffer that contains the data to write.

I have got somewhat working save it disk as a *.tga, but when saving as *.bmp it renders incorrectly.

As *.tga As *.bmp

I believe that the size of byte[] is incorrect and that my data is truncated.

Any hints/tips/ideas on what is going on here would be greatly appreciated. Links to articles explaining byte layout and pixel formats etc. would be helpful.

Thanks!!

C++/CLI code.

  FT_Bitmap *bitmap = &face->glyph->bitmap;

  int width = (face->bitmap->metrics.width / 64);
  int height = (face->bitmap->metrics.height / 64);

  // must be aligned on a 32 bit boundary or 4 bytes
  int depth = 8;
  int stride = ((width * depth + 31) & ~31) >> 3;
  int bytes = (int)(stride * height);

  // as *.tga
  void *buffer = bytes ? malloc(bytes) : NULL;

  if (buffer)
  {
    memset(buffer, 0, bytes);
    for (int i = 0; i < glyph->rows; ++i)
      memcpy((char *)buffer + (i * width), glyph->buffer + (i * glyph->pitch), glyph->pitch);
    WriteTGA("Test.tga", buffer, width, height);              
  }

  array<Byte>^ values = gcnew array<Byte>(bytes);  
  Marshal::Copy((IntPtr)glyph->buffer, values, 0, bytes);

  // as *.bmp
  Bitmap^ systemBitmap = gcnew Bitmap(width, height, PixelFormat::Format24bppRgb);

  // create bitmap data, lock pixels to be written.
  BitmapData^ bitmapData = systemBitmap->LockBits(Rectangle(0, 0, width, height), ImageLockMode::WriteOnly, bitmap->PixelFormat);
  Marshal::Copy(values, 0, bitmapData->Scan0, bytes);
  systemBitmap->UnlockBits(bitmapData);

  systemBitmap->Save("Test.bmp");

Reference, FT_Bitmap

typedef struct  FT_Bitmap_
  {
    int             rows;
    int             width;
    int             pitch;
    unsigned char*  buffer;
    short           num_grays;
    char            pixel_mode;
    char            palette_mode;
    void*           palette;

  } FT_Bitmap;

Reference, WriteTGA

bool WriteTGA(const char *filename, void *pxl, uint16 width, uint16 height)
{
  FILE *fp = NULL;
  fopen_s(&fp, filename, "wb");
  if (fp)
  {
    TGAHeader header;
    memset(&header, 0, sizeof(TGAHeader));
    header.imageType = 3;
    header.width = width;
    header.height = height;
    header.depth = 8;
    header.descriptor = 0x20;

    fwrite(&header, sizeof(header), 1, fp);
    fwrite(pxl, sizeof(uint8) * width * height, 1, fp);

    fclose(fp);

    return true;
  }
  return false;
}

© Stack Overflow or respective owner

Related posts about freetype

Related posts about freetype2