LOGFONT::lfHeight 指定によるフォントサイズの差基本的に "Courier","MS Sans Serif","System","MS ゴシック","FixedSys" ではマッピングモードと LOGFONT::lfHeight ( 以下 lfHeight ) に関連性はありませんでした。すなわちマッピングモードに関わらず,さらに lfHeight の正負に関わらずウィンドウ上には lfHeight の絶対値を以って描画されます。ただしどのフォントも ::TextOut() API で指定すべき Y 座標はそれぞれのマッピングモードについて差異が生じます。
以下の図はそれぞれのマッピングモードについて "Terminal","MS UI Gothic" で描画したものです。( ただし "MS UI Gothic" は事情によってはキャプチャ画面を載せていない場合もあります )
※ lfHeight に設定する値の単位名として適切な呼び名を知らないので,以下では簡単に「単位」と呼んでいます。
下はマッピングモード = MM_LOENGLISH,フォント = "Terminal",lfHeight = 18 単位で文字列を描画した図です。タイトルバーの通りストックオブジェクト OEM_FIXED_FONT を元にし,上段はそのまま,下段は lfHeight を -18 単位にしました。
負の値を与えた場合,文字が通常よりも若干小さく描画されています。MM_LOENGLISH は 1 座標単位を 0.01 インチとしているため,18 x 0.01 = 0.18 インチ = およそ 0.46cm として表示されています。私の現在のディスプレイでは 20cm = 768ドットとなっているので,0.46cm とは 768 x 0.46 / 20 = およそ 17.6 ドット前後となるはずですが,実際に描画されたものは,17 ドットよりも小さい文字でした。
"Terminal" フォントのサイズには 17,14,10,6,4 単位が用意されていますが,見た感じ 10 単位が使用されたようです。この挙動については良い説明ができないので課題ですか。
はたまた,計算式が違ってたりして。
MM_LOENGLISH のデバイスコンテキストでは下に行く程 Y 座標の値が小さくなります。また原点 (0, 0) はデバイス ( ここではウィンドウのクライアント領域 ) の左上となります。従って上図の 1 行目を描画する際には
::TextOut(dc, 0, 0, str, strlen(str));
ですが,2 行目の場合は Y 座標はマイナスの値をとり
::TextOut(dc, 0, -20, str, strlen(str));
とします。
DEFAULT_GUI_FONT ストックオブジェクトから取得した "MS UI Gothic" では 2 つの行に違いは確認できませんでした。ただしこれは "MS UI Gothic" がマッピングモードの変更に対応していないなどの理由ではなく,おそらく誤差 ( 多少複雑な計算式で lfHeight から実際に描画するフォントの高さを計算すると仮定 ) の丸められた結果がたまたま両行とも一致したものと考えられます。なお 2002-09-12 で取り上げた通り,DEFAULT_GUI_FONT ストックオブジェクトから取得した "MS UI Gothic" のデフォルトの lfHeight は -12 単位です。
マッピングモード = MM_HIENGLISH,フォント = "Terminal",lfHeight = 18 とした場合の結果です。下の行は lfHeight を -18 にしています。
このマッピングモードでは 1 座標単位 = 0.001 インチとなり,下の行の文字がかなり細かく描画されました。
次はフォント = "MS UI Gothic",lfHeight = -12 とした場合。DEFAULT_GUI_FONT ストックオブジェクトはデフォルトでは lfHeight がマイナスの値をとります。ここで "下の行"は lfHeight を 12 にして描画しましたが・・
確かに描画したはずの"下の行"がすでに見えなくなってしまっています。この事から "MS UI Gothic" フォントはきちんとマッピングモードの違いによりフォントサイズが計算される事が推察されます。
" 2 行目" 描画時は MM_LOENGLISH に比べて座標単位の倍率が 1/10 になった事を考慮し,Y 座標の値を 10 倍にしてやります。
::TextOut(dc, 0, -200, str, strlen(str));
マッピングモード MM_LOMETRIC では次のようになります。
MM_LOENGLISH と大差がないように見えますが,倍率は多少異なっています。2 行目を描画したコードは次の通り。
::TextOut(dc, 0, -40, str, strlen(str));
MM_LOENGLISH の場合の 2 倍の Y 座標を用いていますが,1 インチ ≒ 2.4cm ということで正確には約 2.4 倍することで MM_LOENGLISH のそれと等価になります。文字の大きさは 1/2.4 となっているはずですが,ディスプレイでは解像度が低いために細かくは認識できません。
"MS UI Gothic" -12 単位では次のようになります。
MM_LOENGLISH では上の行と下の行に差異が見られませんでしたが,この図でははっきりと違いが出ています。大きさも丁度半分〜1/3 程度 ( 理論値は 1/2.4 ) かと。
MM_HIMETRIC の場合は次のようになりました。見た目では MM_LOMETRIC と変わっていません。
文字の大きさは MM_LOMETRIC に比べて 1/10 になるはずですが,なおも点のような文字が出力されています。それに対して "MS UI Gothic" -12 単位では下の行が表示されなくなりました。あまりにも小さくてサイズが 0 に限りなく近づいたからですね。
MM_TWIPS の TWIPS とは TWentIeth of Point の略で 1/20 ポイントを指します。そして 1 ポイントは 1/72 インチと定義されており,結局は 1/1440 インチを表します。MM_HIENGLISH ( 1/1000 インチ ) にほぼ近い倍率です。
"Terminal" フォントは 0 に限りなく近いサイズが用意されていないため,用意された中で一番近いサイズ = 4 が選択されているものと思われます。
"MS UI Gothic" フォントではやはり 2 行目には何も表示されませんでした。
少なくともストックオブジェクトから得たフォントハンドルで素直に描画すれば,マッピングモードに関わらず期待通りの出力が得られます。
マッピングモードの影響を描画されるフォントの大きさにも反映させたい場合は lfHeight の符号を反転させます。ただしこれは "Terminal" や "MS UI Gothic" など,フォントサイズが可変であるもののうち,ごくわずかなフォントにしか適用されません。
今回は MM_ISOTROPIC と MM_ANSITROPIC には触れませんでした。それは,上で行った議論のみで充分にマッピングモードとフォントサイズの関係について語ることができるのと,面倒くさかったから〜。
written by kuri|minima. (warai