サンプルコードのダウンロード

では、まずサンプルコードをダウンロードし、解凍してください。
私はVisual C++6.0でコンパイルしているので、をお持ちの方はVisual C++でプロジェクトファイルを開いてください(「effec_01.dsw」をダブルクリックすれば開けます)。
圧縮ファイルに含まれる「effec_01.exe」をダブルクリックし、実行してみてください(何かキーを押すと終了します)。
どうでしょう?画面が切り替わり、文字が表示されると思います。
というわけで今回は、True Typeフォントを使用した文字列描画について説明したいと思います。

やっぱり苦手なGDI

何のフォントも設定しないまま文字列を出力する方法は「DirectDraw基礎 第4回」、「DirectDraw基礎 第6回」で既にやりました。
今回は、True Typeを使用するという事で、フォントを作成しなければなりません。

ではサンプルコードを順番に説明していきます。

TextOutFont関数が今回作成した自作関数です。

//----------[ True Typeフォントを使用したテキストの出力 ]---------------------------------------
void TextOutFont(LPDIRECTDRAWSURFACE surface, int x, int y, int height, char *text_str, char *font_name, unsigned char col){

	HFONT new_font,old_font;
	HDC hdc;

	//フォント作成
	new_font=CreateFont(
		height,	//高さ
		0,	//横幅
		0,	//角度
		0,	//よくわからなんだ
		FW_NORMAL,	//太さ
		0,	//斜体
		0,	//下線
		0,	//打ち消し
		DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY,DEFAULT_PITCH,font_name);
	
	surface->GetDC(&hdc);			//デバイスコンテキスト取得
	SetBkMode(hdc,TRANSPARENT);			//背景モード設定
	old_font=(HFONT)SelectObject(hdc,new_font);	//フォント選択
						//フォントカラー設定
	SetTextColor(hdc,RGB(peEntry[col].peRed,peEntry[col].peGreen,peEntry[col].peBlue));
	TextOut(hdc,x,y,text_str,strlen(text_str));	//出力
	SelectObject(hdc,old_font);			//フォント復元
	surface->ReleaseDC(hdc);			//デバイスコンテキスト解放
	DeleteObject(new_font);			//フォント消去
}

略

//----------[ メイン関数 ]----------------------------------------------------------------------
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow){

	略

	//メッセージループ
	while(1){
		//テキスト出力
		ClearScreen(lpBack);
		
		//ノーマル
		TextOutFont(lpBack,0,0,60,"Takabo Soft 2000","Comic Sans MS",1);

		略

		Flip();

まず、CreateFont関数を呼び出して、フォントを作成します。書式は以下の通りです。

書式 HFONT CreateFont( int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight, DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut, DWORD fdwCharSet, DWORD fdwOutputPrecision, DWORD fdwClipPrecision, DWORD fdwQuality, DWORD fdwPitchAndFamily, LPCTSTR lpszFace ); ながっ!
nHeight フォントの高さを論理単位で指定。ドット数では無いらしい。0を指定すると、デフォルトの高さになる。
nWidth フォントの横幅を指定。0を指定すると、高さにあった横幅になる。
nEscapement 文字列全体の角度を1/10度単位で指定します。
nOrientation 各文字の角度を1/10度単位で指定します。とか言ってるけど、うちじゃうごかなんだ・・・。
fnWeight フォントの太さを指定します。指定する値は0~1000ですが、400で通常、700でボールド体です。
fdwItalic 1を指定すると斜体になります。
fdwUnderline 1を指定すると下線が付きます。
fdwStrikeOut 1を指定すると打ち消し線が付きます。
fdwCharSet フォントの文字セットを指定するらしい。よく解らないのでDEFAULT_CHARSETを指定(爆
fdwOutputPrecision 出力精度を指定するらしい。よく解らないのでOUT_DEFAULT_PRECISを指定(爆2
fdwClipPrecision クリッピング精度を指定するらしい。やっぱりよく解らないのでCLIP_DEFAULT_PRECISを指定(爆3
fdwQuality 出力品質を指定するらしい。・・・よく解らないのでDEFAULT_QUALITYを指定(爆4
fdwPitchAndFamily フォントのピッチとファミリを指定するらしい。なんじゃそりゃ!というワケでDEFAULT_PITCHを指定(爆5
lpszFace フォント名を指定します。
戻り値 成功すると、論理フォントのハンドルが返るらしい。

というように、私にも一部ワケが解りませんが、フォントが作成し終わったら、デバイスコンテキスト取得し、「SelectObject」を呼び出しています。
この関数は、指定したデバイスコンテキストにGDIのオブジェクト(フォント・ペン・ブラシ等)を選択する(関連づけさせるというべきか・・・)ものです。
この関数の戻り値は、今まで選択されていたGDIのオブジェクトです(新しくフォントを指定したら、今まで選択されていたフォントが戻り値となる)。

こうしてTextOut関数を呼び出してやれば、設定したフォントで文字列を描画してくれるわけです。
描画し終えたら、後始末としてSelectObjectで元のフォントを選択してやります。
昔この作業をサボったら動作がおかしくなったような気がしましたが今やってみると、そんなこともありませんねぇ・・・。
いらなくなったフォントとかを消す前にこうして、元のフォントをSelectObjectで選択させるというのが正しい方法なので、一応やっておいた方が良いと思います。

最後に、DeleteObject関数で、最初に作成したフォントを削除してやります。この作業をサボルと間違いなくウィンドウズはおかしくなります(爆。
ウィンドウズにはGDIリソースというのがあり、CreateFont関数のようにGDIの何かを作成する度に
GDIリソースが減っていきます。このリソースは普段のウィンドウズでも使用しているため、どっかのアプリケーションでこれを使い尽くしてしまうと、他のアプリケーションまで動かなくなるという事態が起きるので、要らなくなったら、ちゃんと消してやりましょう。

ちょっとした飾り付け

True Typeフォントで描画した場合、だいぶ陳腐なものになりがちですが、影や縁を付ける事で多少ながらマシになるかもしれません。

//影付き
TextOutFont(lpBack,0+2,100+2,60,"影付き","MS ゴシック",0);
TextOutFont(lpBack,0,100,60,"影付き","MS ゴシック",1);

//縁付き
TextOutFont(lpBack,0,200-1,60,"縁付き","MS 明朝",0);
TextOutFont(lpBack,0,200+1,60,"縁付き","MS 明朝",0);
TextOutFont(lpBack,0-1,200,60,"縁付き","MS 明朝",0);
TextOutFont(lpBack,0+1,200,60,"縁付き","MS 明朝",0);
TextOutFont(lpBack,0,200,60,"縁付き","MS 明朝",1);

今回は、TextOutFontを並べて影を付けたりしていますが、この関数を呼ぶ毎にフォント作成したり
しているので、アルゴリズム上よくないですよね?影を付ける機能なんかは、TextOutFont関数内に組み込んでしまった方が良いですね。
この辺は各自改造していってください。

フォントの注意点

True Typeフォントを使用する場合、実行するパソコンに使用するフォントがインストールされていなければなりません。
また、制作者のパソコンにフォントがあるからと言ってそれを使用した場合でも、そのプログラムを配布した先のパソコンにそのフォントがインストールされているかも解りません。
ですから、ウィンドウズに標準でインストールされているフォント以外の使用はお薦めできません(自作のフォントなら配布出来ると思いますが)。

「MS P明朝」だとか「MS Pゴシック」ならまず入ってると思います。

また、このような問題の解決策として、絵(BMP)で描いた文字を使用するという手もあります。
これもまたいつか紹介しましょうか。

記事検索

アーカイブ