スポンサーリンク

FreeType2を試す-2 文字列を描画してみる

#include <string>
#include <array>

#include <ft2build.h>
#include FT_FREETYPE_H

#pragma warning(disable:4996)

#pragma comment(lib,"freetyped.lib")

const int imageWidth = 1000;
const int imageHeight = 300;
std::array<unsigned char, imageWidth* imageHeight> image;
int pixel_pos(const int x, const int y) {
  return y * imageWidth + x;
}

void draw(const FT_Bitmap& bmp,int startx, int starty) {

  int Width = bmp.width;
  int Height = bmp.rows;

  for (size_t y = 0; y < Height; y++) {
    for (size_t x = 0; x < Width; x++) {

      int xx = startx + x;
      int yy = starty + y;

      if (xx < 0)continue;
      if (yy < 0)continue;

      if (bmp.buffer[y*Width+x]) {
        image[pixel_pos(xx, yy)] = 1;
      }
    }
  }

}
//! @brief PBM(1byte,テキスト)を書き込む
//! @param [in] fname ファイル名
//! @param [in] width 画像の幅
//! @param [in] height 画像の高さ
//! @param [in] p 画像のメモリへのアドレス
//! @details 1画素1Byteのメモリを渡すと、0,1テキストでファイル名fnameで書き込む
void pbmP1_Write(const char* const fname, const int width, const int height, const unsigned char* const p) { // PPM ASCII

  FILE* fp = fopen(fname, "wb");
  fprintf(fp, "P1\n%d\n%d\n", width, height);

  size_t k = 0;
  for (size_t i = 0; i < (size_t)height; i++) {
    for (size_t j = 0; j < (size_t)width; j++) {
      fprintf(fp, "%d ", p[k]?0:1);
      k++;
    }
    fprintf(fp, "\n");
  }

  fclose(fp);
}
int main()
{

  FT_Library  library; // handle to library
  FT_Error error;
  
  error = FT_Init_FreeType(&library);
  if (error)
    return -1;

  FT_Face face;      // handle to face object

  // フォントファイル読み込み
  error = FT_New_Face(
    library,
    "C:\\Windows\\Fonts\\meiryo.ttc",
    0,
    &face
  );

  //文字コード指定
  error = FT_Select_Charmap(
    face,               // target face object
    FT_ENCODING_UNICODE // エンコード指定
  );


  if (error == FT_Err_Unknown_File_Format)
    return -1;
  else if (error)
    return -1;

  //この二つの値でフォントサイズ調整
  FT_F26Dot6 fontsize=16*64;
  FT_UInt CHAR_RESOLUTION = 300;
  error = FT_Set_Char_Size(
    face,                // handle to face object
    0,                   // char_width in 1/64th of points
    fontsize,            // char_height in 1/64th of points
    CHAR_RESOLUTION,     // horizontal device resolution
    CHAR_RESOLUTION);    // vertical device resolution


  int pen_x=0;
  int pen_y=0;

  std::wstring chars = L"いろ は。にほへと,abc d";
  for (size_t k = 0; k < chars.size(); k++) {

    // 文字の取得
    FT_ULong character = chars[k];
    FT_UInt char_index = FT_Get_Char_Index(face, character);

    // グリフ(字の形状)読込
    error = FT_Load_Glyph(face, char_index, FT_LOAD_RENDER);
    if (error)
      return -1; // ignore errors

    // 文字を画像化
    FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);

    // 画像書き込み
    draw(
      face->glyph->bitmap,
      pen_x + face->glyph->bitmap_left,
      pen_y - face->glyph->bitmap_top + 100
    );
    // 描画位置を更新
    pen_x += face->glyph->advance.x >> 6;
    pen_y += face->glyph->advance.y >> 6; // not useful for now
  }

  // ファイル書き込み
  pbmP1_Write(
    "C:\\test\\freetypetest.pbm",
    imageWidth,
    imageHeight,
    &image[0]
  );

  // FreeType2の解放
  FT_Done_Face(face);
  FT_Done_FreeType(library);
}

出力結果

ピクセル数で指定

  /*
  //この二つの値でフォントサイズ調整
  FT_F26Dot6 fontsize = 16 * 64;
  FT_UInt CHAR_RESOLUTION = 300;
  error = FT_Set_Char_Size(
    face,                // handle to face object
    0,                   // char_width in 1/64th of points
    fontsize,            // char_height in 1/64th of points
    CHAR_RESOLUTION,     // horizontal device resolution
    CHAR_RESOLUTION);    // vertical device resolution
  */

  FT_Set_Pixel_Sizes(
    face,     // handle to face object
    0,        // pixel_width  
    64        // pixel_height
  );

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: