Home | Lesson | Game | Tool | Link

A02.日本語表示

外部DLLを使用せずに、日本語を表示します。
日本語フォントを出力した画像を利用して描画しています。
使用可能な日本語は画像サイズの都合上、第1水準までの漢字になります。
半角カナには対応しておりません。
(小さい画像を利用すれば、第2水準の漢字まで可能になります。)


定義
書式付文字列を扱うのでstdarg.hをインクルードしておきます。
#include <stdarg.h>

画像描画
日本語文字を画像で用意しているので、DrawImageを利用して描画します。
画像なので、拡大縮小や色変更も可能となります。
void DrawImage(IVideoDriver *driver, char* filename, int x, int y, 
	int w, int h, int u, int v, SColor col, SColor col2, float sx, float sy)
{
	ITexture* texture = driver->getTexture(filename);

	SColor col3 = col2;
	if(col2 == 0)col3 = col;
	SColor color[] = {col,col3,col3,col};//左上:左下:右下:右上
	driver->draw2DImage(texture, rect<s32>(x,y,x+w*sx,y+h*sy), 
		rect<s32>(u,v,u+w,v+h), 0, color, true);
}

文字描画
指定した場所に指定した色で文字を描画します。
書式付文字列にも対応しています。
文字の計算方法にはSJISを基準に計算しています。

処理の内容としては、以下の通りです。
1.書式付文字列を通常の文字列に変換します。
2.1文字取得し2バイト文字か1バイト文字か判定します。
3-1.2バイト文字だった場合は、次に関係するもう1バイトを取得します。
3-2.画像の取得する位置を取得して描画します。
4-1.1バイト文字だった場合は、通常文字かどうか判定します。
4-2.特殊文字(改行/タブ)だった場合は、特殊な処理を行います。
4-3.通常文字の場合は、画像の取得する位置を取得して描画します。
void Printf(IVideoDriver *driver, int x, int y, SColor color, const char *fmt, ...)
{
	int i,len;
	va_list ap;
	char tmp[1024];
	char *tex = "japanese.png";

	memset(tmp, 0x00, sizeof(tmp));

	//書式付文字列を調整
	va_start(ap, fmt);
	vsprintf(tmp, fmt, ap);
	va_end(ap);

	len = strlen(tmp);

	int posx = 0;		//文字の描画位置
	int posy = 0;		//文字の廟が位置
	int tx, ty;		//画像読み込み位置
	int w;			//文字の幅  半角文字は8、全角文字は16
	int h = 16;		//文字の高さ 16固定
	unsigned char buf[2];	//取得した文字を一時保存
	
	for(i=0;i<len;i++)
	{
		buf[0] = tmp[i]&0xFF;
		//2バイトチェック(SJIS)
		if((buf[0] >= 0x80 && buf[0] <= 0x9F) || buf[0] >= 0xE0)
		{
			//2バイト文字処理
			w = 16;
			buf[1] = tmp[++i]&0xFF;//次のバッファ取得
			//画像位置計算
			tx = ((buf[1]-0x40)%64)*h;
			ty = (1+(buf[0]-0x81)*3+(buf[1]-0x40)/64)*h;
			DrawImage(driver,tex,x+posx,y+posy,
				w,h,tx,ty,color,color,1,1);
			posx += w;
		}
		else
		{
			//1バイト文字処理
			w = 8;
			switch(buf[0])
			{
				//改行
				case '\n':
					posx = 0;		//開始位置を0にする
					posy += h;	//文字の高さ分ずらす
					break;
				//タブ
				case '\t':
					posx += w*4;	//半角文字4文字分ずらす
					break;
				//通常文字
				default:
					//画像位置計算
					tx = (buf[0]-0x20)*w;
					ty = 0;
					DrawImage(driver,tex,x+posx,y+posy,
						w,h,tx,ty,color,color,1,1);
					posx += w;
					break;
			}
		}
	}
}

描画
Printfを利用して文字を表示します。
書式付文字列に対応しているので、複数の引数を付けることも可能です。
また、カラーを変更することも可能です。
void makeScene(IVideoDriver *driver)
{
	char* mess = "計算:";
	Printf(driver,0,0,0xFFFFFFFF, 
		"こんにちはIrrlicht\n\t%s 10+20=%d", mess, 10+20);
	Printf(driver,0,120,0xFFFFFF00,"色のついた文字列");
}

ダウンロード
今回作成したファイル一式です。

宿題
1.文字を縦方向に2倍にして表示してみましょう。
2.文字を太字にして表示してみましょう。
3.影つきの文字を表示してみましょう。