GetGlyphOutline関数のフォント位置
Windows APIであるGetGlyphOutline関数は、指定のフォント文字のビットマップ情報を取得できます。しかも、アンチエイリアス付きです。フォントを扱う人にとっては大変にありがたい関数なのですが、いかんせんこの関数から返されるビットマップの幅と高さは、フォントがきっちりと入る大きさしかありません。つまり、文字の位置情報は完全に無視されているのです。
ここでは、GetGliphOutline関数を使った後のフォントの位置決めについてしっかりまとめてみます。
GetGlyphOutline関数の使い方は難しくはありません。一応下にまとめます。
DWORD GetGlyphOutline( HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPVOID lpvBuffer, CONST MAT2* lpmat2 );
hdcはデバイスコンテキストハンドルです。GetDCで得られます。
uCharは文字に割り当てられているコード番号です。例えばchar c='a';と定義した時のcがそれに当たります。日本語のような2バイト文字の場合、最初に先導コードがあり、次に文字コードがあります。この場合2バイトをUINTに置き換えて渡せば、正しい文字を認識してくれます。
uFormatは関数が返すデータフォーマットを指定します。幾つかフラグがありますが、ここで重要なのは以下の3つです。
・ GGO_GRAY2_BITMAP 5段階のアンチエイリアス付きビットマップ
・ GGO_GRAY4_BITMAP 17段階のアンチエイリアス付きビットマップ
・ GGO_GRAY8_BITMAP 65段階のアンチエイリアス付きビットマップ
lpgmはGLYPHMETRICS構造体へのポインタを渡します。ここにglyph(象形文字)の情報が格納されます。
cbBufferは次のlpvBufferのサイズを指定します。ここに0を指定すると、関数は必要なバッファサイズを返します。
lpvBufferはビットマップ情報を受け取るバッファへのポインタを渡します。サイズはcbBuffer以上でなければなりません。
pmat2は文字の変換行列で、MAT2という行列構造体へのポインタを渡します。NULLを渡す事が出来ないので、面倒でも行列を作る必要があります。
日本語のビットマップを取得する例をこちらに記述します。
重要なのはここからです。文字をそろえるためには、1文字の空白を含めた全範囲を知る必要があります。下の図をご覧下さい。
XY軸はフォントの空白部分を含むオレンジ色のボックスの座標軸です。青いボックスはGetGlyphOutlineで取られたフォントぎりぎりの範囲です。色々名前がついていますが、頭に「gm」と書かれているのはすべてGLYPHMETRICS構造体のメンバ変数です。頭文字が「tm」なのは、TEXTMETRIC構造体のメンバ変数になります。この図から、オレンジ色のボックスの横はgmCellIncX(GLYPHMETRICS構造体)、縦はtmHeightであることがわかります。これで、空白部分を含めた大きさはわかりました。
次にフォントの位置を決めます。フォントの位置は上図の☆マークの座標が分かればOKです。このx座標はGLYPHMETRICS構造体のgmGliphOrigin.xです。y座標が少し面倒なんですが、tmHeightからtmDesentとgmGlyphOrign.yを引いた値となります。ちなみに、BaseLineより上は「tmAscent」と言います。よって、tmAscentからgmGlyphOrign.yを引いても☆のy座標が求まります。こちらの方が簡単ですね。
まとめますと、GetGlyphOutline関数で得たフォントのビットマップの書き出し位置は
(gmGliphOrigin.x, tmAscent - gmGlyphOrign.y)
となります。