SS blog

C/C++/javaについての話題

CreateFont の引数は何故に沢山?

CreateFont はWindowsアプリケーションのプログラムが文字を描画するためにフォントを選択するときに使用するAPIです。

その引数は下記の通りで、うんざりするほどの数です。

指定したいのはフォント名、太字、斜体、サイズくらいなのになにゆえにこれほど沢山なのでしょう。

この点、よく理解するとフォントの仕組みをよりよく理解できると思うので今回のテーマとします。

HFONT CreateFont(
  [in] int     cHeight,
  [in] int     cWidth,
  [in] int     cEscapement,
  [in] int     cOrientation,
  [in] int     cWeight,
  [in] DWORD   bItalic,
  [in] DWORD   bUnderline,
  [in] DWORD   bStrikeOut,
  [in] DWORD   iCharSet,
  [in] DWORD   iOutPrecision,
  [in] DWORD   iClipPrecision,
  [in] DWORD   iQuality,
  [in] DWORD   iPitchAndFamily,
  [in] LPCWSTR pszFaceName
);

CreateFont はこれら引数で指定したフォントを取得する、と思ってしまうと実際にAPIを使用した時に結果に戸惑ってしまうことがあるでしょう。

より正しい理解は、これら引数はフォントを選ぶ「ヒント」に過ぎないという事です。

Windowsはフォントマッパーという機能を持っており、与えられたヒントに最も適合するフォントを選ぶように善処します。

なのでCreateFont が正常終了したからと言って、指定したフォントが使われているとは限りません。フォントがシステムにインストールされていてもいなくてもCreateFont は正常終了します。

もしインストールされていなければ他の引数で最適な別のフォントを使用します。

またインストールされていても別のフォントを使う事があります。例えば「Times New Roman」はインストールされてはいますが、持っているのは英数字だけですので、日本語の文字列の描画には使えない訳ですから、この場合フォントマッパーが最善のフォントを探し出して使用してくれます。

そういえばCreateFont  APIの解説には「論理フォント」という言葉が使われていました。「Times New Roman」とか「MS Gothic」とかは物理フォントですが、CreateFont が作成する論理フォントは、インストールされた物理フォントの中から最善のものが使われるという点で論理フォントという事です。

フォントの情報

引数はフォント選択のヒントだと書きましたが、例えばFF_SWISSとしてした場合、プロポーショナルフォントでセリフ無しのフォントを求めることになります。

フォントマッパーは個々のフォントにセリフがあるかをどうやって判断しているのでしょうか。言わずもがなフォント自体がそういう属性データを保持しています。

とは言えWidndowsのフォント一覧を見てみると、そういう属性は見当たりません。それはWindowの一覧では表示していないだけです。

Windowsのフォント一覧の表示

専用のビューワーでフォントの名部のデータを照会したのが下記の画像です。

フォントファイル内の「OS/2」というテーブルにそれはあります。

MS Gothic フォントの内部データ

「panose」と「Unicode Range」という名のデータがフォント選択に深くかかわっています。

panoseは10バイトのデータで、各バイトがフォントの特徴を示す10個の情報となっています。セリフの有無などもpanoseを照会すれば直ぐに分かるというわけです。

Unicode Rangeは、フォントファイルに納められた文字の範囲を示しています。文字列を描画するときに、このフォントが使えるのかを直ぐに調べることができます。

それと肝心のフォント名ですが、これは「name」というテーブルに格納されています。

nameテーブル

フォントファミリー名が英語、日本語それぞれの「1」に格納されていますが、Excel等でフォントを選択したときに「MS Gothic」としても「MS ゴシック」としても同じフォントが選択されるのはこれによります。