復習:気合のGetGlyphOutline

α付きフォントを生成するAPI関数で、DirectXでキレイな文字を高速で表示したい時に使われたりするようです。ていうか使ってました(^^; もう3年も前になるのか・・・
そのとき参考にしたページ。
http://richa850.hp.infoseek.co.jp/programming/win04.html
ちょうどそのときもテクスチャに書き出したかったので好都合でした。しかしこのページの著者曰くに、バグがあるかもしれないとか。実際、某環境ではなぜかうまくいかない(’’ 原因は未だ不明なのだがもし本当にバグがあるなら修正したいところ。
というわけで復習も兼ねて元のソースからGetGlyphOutline関係部分だけを切り取り、表示は標準関数で行うサンプルコードを書いてみました。

#include <windows.h>
#include <iostream>
#include <string>


int main()
{
	//サイズを入力
	DWORD fontHeight(0);
	std::cout << "フォントの高さを入力" << std::endl;
	std::cin >> fontHeight;
	//文字を入力
	std::string st;
	std::cout << "文字を入力(全角もOK)" << std::endl;
	std::cin >> std::ws >> st;

	//文字コード設定
	DWORD code = ( static_cast< DWORD >( st[0] ) & 0x000000ff ) ;
	if( (( 0x00000081 <= code ) && ( code < 0x000000A0 )) || (( 0x000000E0 <= code ) && ( code < 0x000000FF )) ){
		code = ( ( code << 8 )  | ( static_cast< DWORD >( st[1] ) & 0x000000ff ) );
	}

	//フォントの生成
	HDC	hdc = ::CreateCompatibleDC(0);
	HFONT font = ::CreateFont( fontHeight, 0, 0, 0, 400,
		0, 0, 0, SHIFTJIS_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
		PROOF_QUALITY, FIXED_PITCH | FF_MODERN, "MS ゴシック" );
	::SelectObject( hdc, font );

	//フォントのαビットマップを生成
	GLYPHMETRICS gm;
	const MAT2 mat = {{0,1}, {0,0}, {0,0}, {0,1}};
	DWORD size = ::GetGlyphOutline( hdc, code, GGO_GRAY4_BITMAP, &gm, 0, NULL, &mat);
	unsigned char* p = new unsigned char[size];
	::GetGlyphOutline(hdc, code, GGO_GRAY4_BITMAP, &gm, size, p, &mat);

	//各種パラメータの表示
	std::cout << "font height : " << fontHeight << std::endl;
	std::cout << "buffer size : " << size << std::endl;
	std::cout << "BlackBoxSize : " << gm.gmBlackBoxX << "," << gm.gmBlackBoxY << std::endl;
	std::cout << "Cell Iincrement : " << gm.gmCellIncX << "," << gm.gmCellIncY << std::endl;
	std::cout << "Glyph Oringin : " << gm.gmptGlyphOrigin.x << "," << gm.gmptGlyphOrigin.y << std::endl;
	std::cout << std::endl;

	//フォントの簡易表示
	unsigned char* cpp = p;
	for( UINT y = 0; y < gm.gmBlackBoxY; ++y ){
		for( UINT x = 0; x < ( ( gm.gmBlackBoxX + 3 ) & ~3 ); ++x ){
			const char cc = ( *cpp == 0 ) ? ' ' : ( ( *cpp < 11 ) ? *cpp + '0' - 1 : *cpp + 'A' - 11 );
			std::cout << cc;
			++cpp;
		}
		std::cout << std::endl;
	}
	std::cout << std::endl;

	//後始末
	delete[] p;
	::DeleteObject( font );
	::DeleteDC( hdc );

	return 0;
}

まあ標準関数でテキスト表示なので少々無理があるけど作動確認としてなら問題ないかな(^^; 0が表示無しでのこり16階調をそのまま16進数に変換して表示します。
というわけで私信:某環境な方、報告ください(ぇー まあ某環境な方でなくとも結果がヘンだったりした場合、報告あると嬉しいかもです(^^;


まあ問題があるのがGetGlyphOutline側でなくDirectX側という可能性も高いのだけれども。