戻る ホーム 上へ 進む

2.2 TFont

ここでは TFont 特有のことについて解説します。

2.2.1 TFontData のデフォルト値 DefFontData

DefFontData の値を以下に示します (括弧内は対応する プロパティ名です)。

フォントハンドル0
フォントの高さ(Height) スクリーン上での9pt相当(Delphi 1.0J では 10pt)のピクセル数
フォントのピッチ(Pitch)fpDefault
フォントのキャラクタセット(CharSet)SHFTJIS_CHARSET
フォントのスタイル(Style)[]
フォント名(Name) 'MS P ゴシック'(Delphi 1.0J では'System')
VCL のソースコードを見ると、一見
  Height = 0;
  Pitch = fpDefault;
  Style = [];
  Charset = DEFAULT_CHARSET;
  Name = 'MS Sans Serif';

のように見えますが、TFontData のデフォルト値は、Initialization で InitDefFontData を使って初期化されるため、ソースコード上の値とは異なります。これはロケールによってデフォルトフォントを切り替えるためです。

2.2.2 TFontData から TLogFont への変換

Figure 2.2-2

図 2.1-2 TResource(リソース)の構造(再掲)

TFont の プロパティ は TFont のインスタンスとリソースの内の TFontData に別れて格納されます。 TFontData 内のデータはTFontdata 内の「ハンドル」値が0の場合論理フォントを作成するために使われます。TFontData から TLogFont への変換は以下のようになります。

lfHeight := フォントの高さ(Height プロパティ)
lfWidth := 0
lfEscapement := 0
lfOrientation := 0
スタイル(Stype プロパティ)が fsBold を含むなら lfWeight := FW_BOLD 含まないなら lfWeight := FW_NORMAL
スタイル(Stype プロパティ)が fsItalic を含むなら lfItalic := 0 以外 含まないなら lfItalic := 0
スタイル(Stype プロパティ)が fsUnderLineを含むなら lfUnderline := 0 以外 含まないなら lfUnderline := 0
スタイル(Stype プロパティ)が fsStrikeOut を含むなら lfStrikeOut := 0 以外 含まないなら lfStrikeOut := 0
lfFaceName := フォントの名前(Name プロパティ)
lfCharSet := フォントのキャラクタセット(CharSet プロパティ)
lfCharSet := DEFAULT_CHARSET(Delphi 2.0J の場合)
(Delphi 1.0J では 「フォントの名前」の示すフォントが有るかを EnumFonts で調べ、もし有れば、そのフォントの lfCharSet を セットする。無ければ DEFAULT_CHARSET をセットする。)
lfQuality := DEFAULT_QUALITY
lfOutPrecision := OUT_DEFAULT_PRECIS
lfClipPrecision := CLIP_DEFAULT_PRECIS
フォントのピッチ(Pitch プロパティ)= fpVariable なら
lfPitchAndFamily := VALIABLE_PITCH
fpFixed なら lfPitchAndFamily := FIXED_PITCH
fpDefault なら lfPitchAndFamily := DEFAULT_PITCH

2.2.3 Handle プロパティ への代入

2.1.5 で説明した TPen やTBrush の Handle プロパティ とは異なり Handle プロパティ に 論理フォントのハンドルを代入した場合、リソースにセットされるリソースパラメータはデフォルト値ではなく、論理フォントから抽出された値が使われます。つまり、GetObject API を使って論理フォントのパラメータを取得し、フォントのリソースパラメータが抽出されます。変換法は以下の通りです。

フォントの高さ := lfHeight;
lfWeight >= FW_Bold ならフォントのスタイル(Style プロパティ)に fsBold を加える。
lfItalic = 1 ならフォントのスタイル(Style プロパティ)に fsItalic を加える。
lfUnderline = 1 ならフォントのスタイル(Style プロパティ)に fsUnderline を加える。
lfStrikeOut = 1 ならフォントのスタイル(Style プロパティ)に fsIStrikeOut を加える。
フォントのキャラクタセット(CharSet プロパティ) := lfCharSet;
フォントの名前(Name プロパティ) := lfFaceName;
lfPichAndFamily の下位4ビットが
VARIBLE_PITCH なら フォントのピッチ(Pitch プロパティ) := fpVariable;
FIXED_PITCH なら フォントのピッチ(Pitch プロパティ) := fpFixed;
それ以外なら フォントのピッチ(Pitch プロパティ) := fpDefault;

TFont の Handle プロパティ に代入を行った後、Height や Name プロパティ を読むと Handle プロパティ にセットされた 論理フォントから抽出した値が読み出されます。但し、2.1.5 で説明したように、Handle プロパティ 、色(Color プロパティ)とインチ当たりのピクセル数(PixelsPerInch プロパティ)以外の プロパティ を変更すると、代入された論理フォントは消え、リソース内のパラメータ(TFontのプロパティ)でフォントが作り直されます。TFontのプロパティには論理フォントの内容が反映されていますので、全く異なる似ても似つかないフォントに代わってしまうことは有りませんが、完全では有りません。

例えば、論理フォントのパラメータ lfEscapement を利用して回転したフォントを作成し、TFont の Handle プロパティ に代入すれば、傾いた文字列を描くことが出来ますが、TFont の プロパティ の中に lfEscapement に対応するものが無いため、Height プロパティ を変更すると、文字の傾きがなくなってしまいます。

2.2.4 PixelsPerInch プロパティ と Size プロパティ

TFont では、Size プロパティ と PixelsPerInch と Height プロパティの間には

Size = Height * 72 div PixelsPerInch
Height = Size * PixelsPerInch div 72

という関係があります。つまり、TFont は Device Context のマッピングモードが MM_TEXT なのを前提にしています。

TFont の PixelsPerInch の値は デフォルトでは スクリーンデバイスの解像度が用いられますが、TFont が Canvas の プロパティ の場合、その Canvas の解像度が用いられます。例えば TPrinter の Canvas.Font.PixelsPerInch プロパティ はプリンタの縦方向の解像度を表します。PixelsPerInch プロパティ は TFont.Assign メソッドで他の TFont のインスタンスを代入しても変化しません。

TFontは、内部的には Height プロパティ の方しか保持していないため、Size プロパティ は Height を上記の計算式で読み書きすることで実現されています。ところが、にもかかわらず、VCLでは Height プロパティ よりも、Size プロパティ を重要と考えています

TFont.Assign はコピー元とコピー先の TFont の PixelsPerInch プロパティ の値が同じ場合、TFont をリソースをコピー元とコピー先で共有化するように処理します。これは他の グラフィックスオブジェクトと同様です。しかし、コピー元とコピー先の PixelsPerInch プロパティが異なる場合は共有化処理の後にコピー元の Size プロパティ が コピー先の Size プロパティ へ代入されます。つまり、フォントのポイントが一定に保たれるようにするわけです。2.1.52.2.3 で説明したように、コピー元の TFont のインスタンスの Handle プロパティ に論理フォントが代入されている場合で、かつコピー先と PixelsPerInch プロパティ の値が違う場合、コピー先の TFont のインスタンスの Size プロパティ に代入が行われるので、Handle プロパティ に代入されていた論理フォントがコピー先から切り離されてしまいます。注意が必要です。

例えば TPrinter の Canvas.Font に代入する場合、PixelsPerInchプロパティがスクリーンの解像度になっているTFont のインスタンスを代入すると必ずこの問題が起きます。プリンタで特殊なフォントを使いたいときは、TPrinter の Canvas.Font.Handle に論理フォントを直接代入するか、代入(Assign)する TFont のPixelsPerInchをプリンタのものに合わせてください。

戻る ホーム 上へ 進む

inserted by FC2 system