スポンサーリンク

FreeType2を試す-6- 絵文字を出力

絵文字を扱う上で最も重要なことは、絵文字が使えるフォントを指定する点。ただしサンプルで使用しているseguiemj.ttfはアルファベットは使えるが日本語が使えないので、実用的な事を言えば絵文字と絵文字以外でフォントを切り替える必要がある。

あと、UTF32で文字を指定しないと失敗するように思う。

pnmwrite.hpp (出力用関数群)

#pragma once

#include<cstdio>
#include <bitset>


//! @brief PBM(1byte,テキスト)を書き込む
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);
}

//! @brief PGM(1byte,テキスト)を書き込む
void pgmP2_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, "P2\n%d %d\n255\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]);
      k++;
    }
    fprintf(fp, "\n");
  }

  fclose(fp);
}


//! @brief PPM(1byte,テキスト)を書き込む
void ppmP3_Write(
  const char* const fname,
  const int width,
  const int height,
  const unsigned char* const p
) {

  FILE* fp = fopen(fname, "wb");
  fprintf(fp, "P3\n%d %d\n255\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++) {
      //RGBAなので、* 3でなく* 4にしている
      fprintf(fp, "%d %d %d ", p[k * 4 + 2], p[k * 4 + 1], p[k * 4 + 0]);
      k++;
    }
    fprintf(fp, "\n");
  }

  fclose(fp);
}

プログラム本体

#include <ft2build.h>
#include FT_FREETYPE_H

// MONO変換用
#include FT_BITMAP_H

#pragma warning(disable:4996)

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


#include "pnmwrite.hpp"


int main()
{

  FT_Library  library; // handle to library
  FT_Error error;

  error = FT_Init_FreeType(&library);
  if (error)
    return -1;

  FT_Face face;

  // フォントファイル読み込み
  error = FT_New_Face(
    library,
    "C:\\Windows\\Fonts\\seguiemj.ttf", // 絵文字が使えるフォントを指定
    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 * 2;
  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_ULong character = U'😀'; // UTF32で文字を指定

  FT_UInt char_index = FT_Get_Char_Index(face, character);

  //モノクロ
  error = FT_Load_Glyph(face, char_index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);

  //グレイスケール
  //error = FT_Load_Glyph(face, char_index, FT_LOAD_RENDER );

  //カラー
  //error = FT_Load_Glyph(face, char_index, FT_LOAD_RENDER | FT_LOAD_COLOR);

  if (error)
    return -1; // ignore errors


  int Width = face->glyph->bitmap.width;
  int Height = face->glyph->bitmap.rows;



  switch (face->glyph->bitmap.pixel_mode) {
  case FT_PIXEL_MODE_NONE:
    printf("FT_PIXEL_MODE_NONE");
    break;
  case FT_PIXEL_MODE_MONO:
    printf("FT_PIXEL_MODE_MONO");
    {
      FT_Bitmap glyphbitmap;
      FT_Bitmap_Init(&glyphbitmap);
      FT_Bitmap_Convert(library, &face->glyph->bitmap, &glyphbitmap, 1);

      FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);
      pbmP1_Write(
        "C:\\test\\freetypetest.pbm",
        Width,
        Height,
        glyphbitmap.buffer
      );
    }

    break;
  case FT_PIXEL_MODE_GRAY:
    printf("FT_PIXEL_MODE_GRAY");

    pgmP2_Write(
      "C:\\test\\freetypetest.pgm",
      Width,
      Height,
      face->glyph->bitmap.buffer
    );

    break;
  case FT_PIXEL_MODE_GRAY2:
    printf("FT_PIXEL_MODE_GRAY2");
    break;
  case FT_PIXEL_MODE_GRAY4:
    printf("FT_PIXEL_MODE_GRAY4");
    break;
  case FT_PIXEL_MODE_LCD:
    printf("FT_PIXEL_MODE_LCD");
    break;
  case FT_PIXEL_MODE_LCD_V:
    printf("FT_PIXEL_MODE_LCD_V");
    break;
  case FT_PIXEL_MODE_BGRA:
    printf("FT_PIXEL_MODE_BGRA");

    ppmP3_Write(
      "C:\\test\\freetypetest.ppm",
      Width,
      Height,
      face->glyph->bitmap.buffer
    );

    break;
  }


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

コメントを残す

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

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


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