GameProgrammar's Night

ゲームプログラム系の覚え書き

FreeType2 の FT_Render_Glyph で得られるビットマップバッファの並び

FT_Bitmap

 FT_Render_Glyphで得られるビットマップデータの構造体。こいつを使ってビットマップフォーマットに起こして、ファイルに保存することでビットマップファイルが得られます。

FT_BitmapとBITMAPINFOHEADERの対応

FT_Bitmap BITMAPINFOHEADER 意味
width biWidth ビットマップの幅
rows biHeight ビットマップの高さ
pixel_mode biBitCount モードに合わせてビットカウントや格納されているバッファの並びが決まる

FT_Bitmap::buffer のフォーマット

pixel_mode==FT_PIXEL_MODE_GRAY の時

 FT_Render_Glyph の第三引数にFT_RENDER_MODE_NORMALを指定するとこのピクセルモードになります。
 1バイトごとに1ピクセルの色が入っています。ピクセルの並びは、左上から右下に向けて入っていますので、通常のビットマップ(左下から右上)とは上下逆になっています。そのため、ビットマップファイルとして出力するには上下反転する必要があります。

FT_Bitmap glyph;
bitmap    image; // ビットマップファイルを読み書きするクラスとします

// bitmap基準の座標でデータをコピー
for(int32_t y=0; y<glyph.rows; ++y)
{
   for(int32_t x=0; x<glyph.width; ++x)
   {
      uint32_t i = x+((glyph.rows-1)-y)*glyph.pitch; // 上下反転
      uint8_t  c = glyph.buffer[i]; // FT_Bitmapから色取得

      image.set_pixel(x,y,c,c,c); // すべてのチャンネルに取得した色を入れる
   }
}
pixel_mode==FT_PIXEL_MODE_MONO の時

 FT_Render_Glyph の第三引数にFT_RENDER_MODE_MONOを指定するとこのピクセルモードになります。
 1ビットごとに1ピクセルの色が入っています。ビットが立っていたら色あり、降りていたら色なし、と判断します。ビット並びは左から右に並んでいます。つまり、最上位ビットが1ピクセル目、最下位ビットが8ピクセル目のようになります。
 1ビットごとなので、ピクセルが格納されているはずのバッファ位置を特定し、そこから対応するビットを取得するという手順を踏みます。上下反転も忘れてはいけません。

FT_Bitmap glyph;
bitmap    image; // ビットマップファイルを読み書きするクラスとします

// bitmap基準の座標でデータをコピー
for(int32_t y=0; y<glyph.rows; ++y)
{
   for(int32_t x=0; x<glyph.width; ++x)
   {
      // xはビット単位の位置なので、バイト位置にするため8で割る
      uint32_t i = x/8+((glyph.rows-1)-y)*glyph.pitch;
      uint8_t  c = 0;
      // バッファ内の対応bitが立っているかどうか
      if(glyph.buffer[i] & (0x80>>(i%8))>0)
        c=255;
      else
        c=0;

      image.set_pixel(x,y,c,c,c); // すべてのチャンネルに取得した色を入れる
   }
}