FontRender

http://tokyo.cool.ne.jp/sdl/index9.html のFontRenderというツールはなぜかソースが公開されていないのでそのへんの不満を解消するため書いたものです。
http://www.h4.dion.ne.jp/~zero1341/win01/108.htm からデバイスコンテキストからファイルにビットマップを出力するコードを盗みました。

#include <windows.h>
#include <stdio.h>

HBITMAP hBMP;

void savebmp(HDC hDC, int width, int height, char *filename)
{
  FILE *fp = fopen(filename, "wb");
  if (!fp)
  {
    return;
  }

  // ビットマップからデータを取得
  int nW = ((width*3 + 3)/4)*4;
  int off1 = sizeof(BITMAPFILEHEADER);
  int off = off1+sizeof(BITMAPINFOHEADER);
  int len = off + nW*height;
  BYTE *pIn = new BYTE[len];
  BITMAPFILEHEADER *pF = (BITMAPFILEHEADER*)pIn;
  pF->bfType = 'BM';    // intel系では下から入れるのでファイルではBMになる
  pF->bfSize = len;     // ファイルのサイズ
  pF->bfReserved1 = 0;  // このように決まっている
  pF->bfReserved2 = 0;  // 同上
  pF->bfOffBits = off;  // ファイルの先頭からデータ本体までのオフセット
  BITMAPINFOHEADER *pH = (BITMAPINFOHEADER*)(pIn+off1);
  pH->biSize = off-off1;
  pH->biWidth = width;
  pH->biHeight = height;
  pH->biPlanes = 1;
  pH->biBitCount = 24;       // full color
  pH->biCompression = 0;
  pH->biSizeImage = 0;
  pH->biXPelsPerMeter = 3800;
  pH->biYPelsPerMeter = 3800;
  pH->biClrUsed = 0;
  pH->biClrImportant = 0;
  BITMAPINFO *pI = (BITMAPINFO*)pH;
  GetDIBits(hDC, hBMP, 0, height, pIn+off, pI, DIB_RGB_COLORS);

  // ファイルに書き出す
  fwrite(pIn, 1, len, fp);
  fclose(fp);
  delete pIn;
}

void paintfont(HDC hdc, int x, int y, char *str)
{
	TextOut(hdc, x, y, str, 2);
}

void dopaintascii(HDC hdc, int w, int h)
{
	int i, j;
	int x = 0, y = 0;
	unsigned char b1, b2;
	char str[3];
	for (i=0;i<16;i++)
	{
		for (j=0;j<16;j++)
		{
			str[0] = i*16 + j;
			str[1] = ' ';
			str[2] = '\0';
			paintfont(hdc, x, y, str);
			x += w * 2;
		}
		y += h;
		x = 0;
	}
}

void dopaintkanji(HDC hdc, int i1, int i2, int j1, int j2, int w, int h)
{
	int i, j;
	int x = 0, y = 0;
	unsigned char b1, b2;
	char str[3];
	
	for (i = i1; i <= i2; i++)
	{
		for (j=j1;j<=j2;j++)
		{
			b1 = i; b2 = j;
			str[0] = b1;
			str[1] = b2;
			str[2] = '\0';
			paintfont(hdc, x, y, str);
			x += w * 2;
		}
		y += h;
		x = 0;
	}
}

void main()
{
	int font_h = 16, font_w = 8;
	int bmp_w, bmp_h;
	char *font_name = "MS 明朝";
	HDC hdcscreen, hdcmain;
	HFONT hfont;

	bmp_w = (0x7f - 0x40 + 1) * font_w * 2;
	bmp_h = (0x9f - 0x81 + 1) * font_h;
	hfont = CreateFont(font_h, font_w,
		0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
		DEFAULT_CHARSET, 0, 0, 0, FIXED_PITCH | FF_DONTCARE, 
		font_name);
	hdcscreen = GetDC(NULL);
	hdcmain = CreateCompatibleDC(hdcscreen);
	hBMP = CreateCompatibleBitmap(hdcscreen, bmp_w, bmp_h);
	ReleaseDC(NULL, hdcscreen);

	SelectObject(hdcmain, hBMP);
	SelectObject(hdcmain, hfont);

	SetBkColor(hdcmain, RGB(255, 0, 255));

	char *hajime = "zzfont";
	char filenamebuf[1024];

	Rectangle(hdcmain, -1, -1, bmp_w+1, bmp_h+1);
	dopaintkanji(hdcmain, 0x81, 0x9f, 0x40, 0x7f, font_w, font_h);
	sprintf(filenamebuf, "%s_0000k.bmp", hajime);
	savebmp(hdcmain, bmp_w, bmp_h, filenamebuf);

	Rectangle(hdcmain, -1, -1, bmp_w+1, bmp_h+1);
	dopaintkanji(hdcmain, 0x81, 0x9f, 0x80, 0xbf, font_w, font_h);
	sprintf(filenamebuf, "%s_0001k.bmp", hajime);
	savebmp(hdcmain, bmp_w, bmp_h, filenamebuf);

	Rectangle(hdcmain, -1, -1, bmp_w+1, bmp_h+1);
	dopaintkanji(hdcmain, 0x81, 0x9f, 0xc0, 0xfc, font_w, font_h);
	sprintf(filenamebuf, "%s_0002k.bmp", hajime);
	savebmp(hdcmain, bmp_w, bmp_h, filenamebuf);

	Rectangle(hdcmain, -1, -1, bmp_w+1, bmp_h+1);
	dopaintkanji(hdcmain, 0xe0, 0xfc, 0x40, 0x7f, font_w, font_h);
	sprintf(filenamebuf, "%s_0100k.bmp", hajime);
	savebmp(hdcmain, bmp_w, bmp_h, filenamebuf);

	Rectangle(hdcmain, -1, -1, bmp_w+1, bmp_h+1);
	dopaintkanji(hdcmain, 0xe0, 0xfc, 0x80, 0xbf, font_w, font_h);
	sprintf(filenamebuf, "%s_0101k.bmp", hajime);
	savebmp(hdcmain, bmp_w, bmp_h, filenamebuf);

	Rectangle(hdcmain, -1, -1, bmp_w+1, bmp_h+1);
	dopaintkanji(hdcmain, 0xe0, 0xfc, 0xc0, 0xfc, font_w, font_h);
	sprintf(filenamebuf, "%s_0102k.bmp", hajime);
	savebmp(hdcmain, bmp_w, bmp_h, filenamebuf);
	
	Rectangle(hdcmain, -1, -1, bmp_w+1, bmp_h+1);
	dopaintascii(hdcmain, font_w, font_h);
	sprintf(filenamebuf, "%s.bmp", hajime);
	savebmp(hdcmain, bmp_w, bmp_h, filenamebuf);

	DeleteDC(hdcmain);
}

/*
mika_font_24.bmp 半角文字が横16縦16に並んでいます
mika_font_24_0000k.bmp 1バイト目 0x81〜0x9f 2バイト目 0x40〜0x7f の文字が並んでいます
mika_font_24_0001k.bmp 1バイト目 0x81〜0x9f 2バイト目 0x80〜0xbf の文字が並んでいます
mika_font_24_0002k.bmp 1バイト目 0x81〜0x9f 2バイト目 0xc0〜0xfc の文字が並んでいます
mika_font_24_0100k.bmp 1バイト目 0xe0〜0xfc 2バイト目 0x40〜0x7f の文字が並んでいます
mika_font_24_0101k.bmp 1バイト目 0xe0〜0xfc 2バイト目 0x80〜0xbf の文字が並んでいます
mika_font_24_0102k.bmp 1バイト目 0xe0〜0xfc 2バイト目 0xc0〜0xfc の文字が並んでいます
*/