酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

\Windows Mobile(.NET Compact Framework)のオーナードローでの描画時のフォントサイズの求め方

ちょいメモ。あとで清書する。

SecureMapの犯罪事案の一覧画面は、アイテム毎に「犯罪発生場所」「発生時刻」「タイトル」「詳細」を表示させたいです。当然、通常のListBoxでは1つしか表示出来ないので、必然的にオーナードローで対応する必要が出てきます。

VGAサイズのエミュレータを使って調整をしてて、丁度良い感じになってきたので、QVGAだったら文字が小さすぎないかを確認しようとしたら、VGAとQVGAでは見た目がぜんぜん違う!!

基本的にどんな現像度でもQVGAと同じように描画されるようになっています(なのでリアルVGA化とかあるわけで)。VGAはQVGAとDPIが異なっているのをすっかり忘れてました。フォントサイズをハードコーディングで同じにしていた。

  // タイトル表示 の表示に使用
  Font font1 = new Font("Tahoma", 8, FontStyle.Bold);

  // 場所・発生時間・詳細 の表示に使用
  Font font2 = new Font("Tahoma", 5, FontStyle.Regular);

MSDNオンラインライブラリに、このDPIの時にこのポイントだったら縦何ピクセルになるかを求める計算式が載っています。*1

Windows® オペレーティング システムでは、GDI (Graphics Device Interface) モジュールが、画面への描画とプリンタでの印刷の管理を行っています。この GDI 内部では、フォントのサイズはピクセル (プリンタの場合ドット) の単位で扱われます。例えば、アプリケーション上で 15 ポイントのサイズのフォントを選択した場合、96 dpi の画面上では、以下の計算により、20 ピクセルのフォントが使用されます。

20 (ピクセル) = 15 (ポイント) × 96 (dpi) / 72

この場合、全角文字の幅は 20 ピクセル、半角文字の幅は 10 ピクセルとなり、全角文字の幅が半角文字の幅の 2 倍となります。

Windows Developer Center - Windows XP での全角固定ピッチフォントの仕様変更

上記の計算式をまとめると、以下の式となります。これはフォントのサイズからDPIを考慮してピクセルに変換しています。

pixel = point x dpi / 72

Windows Mobile(というよりは.NET Compact Framework)のFontクラスには、ポイントやピクセルと言った単位を扱うUnitプロパティがありますが、.NET Compact Frameworkは、デスクトップ版のサブせっt(略)なので、Unitプロパティは、GraphicsUnit.Point固定とされています。

コンストラクタ引数でも指定可能な単位は、ポイント固定となっており、描画したい高さに合わせてフォントのポイントも変更しなければいけません。

そこで、先程の式を逆算してポイントを求める式を考えましょう。

point = pixel x 72 / dpi

具体的なソースコードを書きます。

  // 描画したいフォントのサイズ(ポイント単位)を求める
  float font1Point = 14 * 72 / g.DpiY;
  float font2Point = 13 * 72 / g.DpiY;

  // タイトル表示 の表示に使用
  Font font1 = new Font("Tahoma", font1Point, FontStyle.Bold);

  // 場所・発生時間・詳細 の表示に使用
  Font font2 = new Font("Tahoma", font2Point, FontStyle.Regular);

実行した結果です。少し見えにくいかもしれませんが、以下の通り横幅の広さが違います。縦で見ると大体同じになっているのが判るでしょうか。

*1:テキストとフォントについては、このページが参考になります。第 17 章 テキストとフォント