VC++6.0sp6 WindowsXPです。
論理フォントの作成で、フォントサイズがどうしても思ってたより大きく
なってしまうのですが、誰か教えていただけませんでしょうか?
以下はそのソースなのですが、MM_HIMETRICモードで、文字高さ=115の
フォントを作成したのですが、TEXTMETRICを取得してみると、
tmHeight=125になってしまいます。logfont.lfHeightには+115と設定し、
セル高さとしているのですが、ここを-115とし文字高さにしても同じ現象です。
論理フォントから物理フォントにマッピングする際に、必ず同じにはならない
と思いますが、同じか少し小さいくなるぐらいだと思ってました。
これは、フォントマッピングの仕様でしょうか?
void CTESTView::OnDraw(CDC* pDC)
{
CTESTDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: この場所にネイティブ データ用の描画コードを追加します。
// LOGFONT構造体の設定
LOGFONT logfont;
ZeroMemory(&logfont, sizeof(logfont));
logfont.lfHeight = 115;
logfont.lfWidth = 150;
logfont.lfEscapement = 0;
logfont.lfOrientation = 0;
logfont.lfWeight = FW_NORMAL; //FW_DONTCARE;
logfont.lfItalic = FALSE;
logfont.lfUnderline = FALSE;
logfont.lfStrikeOut = FALSE;
logfont.lfCharSet = SHIFTJIS_CHARSET;
logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS | CLIP_LH_ANGLES;
logfont.lfQuality = DEFAULT_QUALITY;
logfont.lfPitchAndFamily = FF_DONTCARE | FIXED_PITCH;
_tcscpy(logfont.lfFaceName, _T(MS ゴシック));
// フォントの生成
CFont font;
font.CreateFontIndirect(&logfont);
pDC->SetMapMode(MM_HIMETRIC);
CFont* pOldFont = pDC->SelectObject(&font);
TEXTMETRIC tm;
pDC->GetTextMetrics(&tm);
TRACE(tm.tmHeight=%d, tm.tmHeight);
pDC->SelectObject(pOldFont);
}
フォント幅「logfont.lfWidth」を「0」にした場合はどうなりますか。
logfont.lfWidth」を「0」にしても、同じでした。
tm.tmHeight=125でした。
> tm.tmHeight=125でした。
ならば、フォンとマッパーは正しいフォントを選択している可能性が高いです。
マッピングモードを設定した以上、そのモードでは
115[論理単位] = (125 - tm.tmDescent)[画面ピクセル単位]
ということです。
若干説明が足りないかもしれないので補足させてもらうと、原理上
MM_TEXT 1[論理単位]=1[ピクセル]を保障
MM_ISOTROPIC 1[論理単位]=自分が決める[ピクセル]値を保障
MM_ANISOTROPIC 1[論理単位]=自分が決める[ピクセル]値を保障
MM_(その他) 1[論理単位]=デバイスドライバとOSが勝手に
決めた[ピクセル]値
と、なっているので、
一般に厳密な物理ピクセル高のフォントが必要な場合
MM_TEXTであきらめるか、完全に自前で算定/設定可能な
MM_ISOTROPIC/MM_ANISOTROPICを使用します。
lf.lfHeight = -MulDiv ( 115, GetDeviceCaps ( hdc, LOGPIXELSY ), 72 ) ;
こんな感じのコードじゃなかったでしたっけ?
> lf.lfHeight = -MulDiv ( 115, GetDeviceCaps ( hdc, LOGPIXELSY ), 72 ) ;
> こんな感じのコードじゃなかったでしたっけ?
MM_TEXTモード限定で、115[ポ]の高さを求めたいなら正解。
この場合72[DPI]という決め打ち値ですね。
MM_HIMETRICモードの場合は、1論理単位がモニター画面上の0.01[mm]に
換算されるので、使用しているモニタディスプレー(又はデバイス)の
DPIに依存します。(自分のモニタは96[DPI]でした)
っつうか、全ての内部データを[mm]等の物理単位で構成すべきで、
何ピクセルか考えること自体がナンセンスのはず。
ナンセンスかもねぎですが・・
これはどうでしょ?
lf.lfHeight = -MulDiv ( 115, 2540, 72 ) ;
>lf.lfHeight = -MulDiv ( 115, 2540, 72 ) ;
115ポイントからHIMETRICの高さを求めるということならこれでいいのかな。
ピクセルからHIMETRICへの変換はCDC::DPtoHIMETRICが使えます。
>>lf.lfHeight = -MulDiv ( 115, 2540, 72 ) ;
>
>115ポイントからHIMETRICの高さを求めるということならこれでいいのかな。
ポイントからピクセルへの変換は論理インチでの解像度を使用しますが、
フォント作成時の渡す高さには、ピクセルから論理単位に変換する時に
物理インチでの解像度を使うべきで、これではダメでした。
CDC::DPtoHIMETRICは物理インチでの変換もできます。