Palm Programmer's Laboratory
Palm OS Programmer's Companion Volume I/8-4
8-4 フォント
Palm OS の全てのフォントはビットマップフォントです。ビットマップフォントはそれぞれの文字がそれぞれのサイズとスタイルを持つビットマップとして提供されるようなフォントです。TrueType や PostScript のようなスケーラブルなフォントはサポートされていません。
それぞれのフォントは特定の文字エンコーディングと関連付けられています。フォントにはそのエンコーディングの各文字をどのように描画するかを定義する文字図形を含んでいます。
Palm OS は組込みのフォントを提供しますが、Palm OS 3.0 以降では独自のフォントを定義することができます。高密度ディスプレイフィーチャセットが存在していれば、高密度ディスプレイにおいて高密度フォントがサポートされます。このセクションでは Palm OS 3.0 以降におけるフォントサポートについて説明します。以下のトピックがあります。
- 組込みフォント
- 使用するフォントの選択
- 高密度ディスプレイ用のフォント
- プログラムからのフォント設定
- フォント情報の取得
- カスタムフォントの作成
高密度ディスプレイに関する全般的な情報については、“高密度ディスプレイ”を参照して下さい。
組込みフォント
Palm OS にはいくつかのフォントが組み込まれています。Font.h ファイルには、プログラムから組み込みフォントにアクセスするのに使用できる定数が定義されています。これらの定数は言語や文字コードに関係なく全てのバージョンの Palm OS で定義されていますが、それらの定数は別のフォントを指している場合があります。例えば、日本語システムにおける stdFont は Latin システムにおける stdFont とはまったく違います。
表 8.1 にテキストの表示に使用できる組み込みフォントを一覧して説明しています。
表 8.1 組み込みのテキストフォント
定数 | 説明 |
---|---|
stdFont | ユーザー入力を表示に使用する小さな標準のフォント。このフォントはできるだけ多くのテキストを表示できるように小さくなっています。 |
largeFont | 標準フォントは読むには小さいと感じるユーザーのために提供される大きなフォントです。 |
boldFont | stdFont と同じサイズですがボールド体のより見易いフォントです。ユーザーインターフェースのテキストラベルなどに使用されます。 |
largeBoldFont | Palm OS 3.0 以降のみ使用可。largeFont と同じサイズのボールドフォントです。 |
図 8.2 に、表 8.1 のそれぞれのフォントがどのように見えるかを示します。
図 8.2 組み込みのテキストフォント
Palm OS は、表 8.2 に示すフォントも定義しています。これらのフォントはほとんどのアルファベット文字を含んでいません。これらは特殊な目的にのみ使用されます。
表 8.2 組み込みのシンボルフォント
定数 | 説明 |
---|---|
symbolFont | 矢印やシフトインジケータなどの特殊文字を含んでいます。 |
symbol11Font | チェックボックスと大きな左矢印、および大きな右矢印を含んでいます。 |
symbol7Font | リピートボタンのスクロール矢印に使用される上下の矢印や、それらの無効化された矢印を含んでします。 |
ledFont | 0 〜 9 の数字、−、.、およびカンマ(,)を含んでいます。Calculator アプリケーションが数値などを表示するのに使用します。 |
使用するフォントの選択
通常のテキストやボールドテキストの表示に使用されるデフォルトフォントは、ハンドヘルドの文字エンコーディングによって異なります。ラテン文字エンコーディングのハンドヘルドは通常 stdFont と boldFont を使いますが、日本語のハンドヘルドではデフォルトで largeFont と largeBoldFont が使われます。アプリケーションの初回起動時には、システムのデフォルト設定を尊重すべきです。FntGlueGetDefaultFontID 関数を使い、デフォルトフォントが何かを取得して下さい( リスト 8.10 参照 )。
リスト 8.10 デフォルトのシステムフォントの取得
FontID textFont = FntGlueGetDefaultFontID(defaultSystemFont); FontID labelFont = FntGlueGetDefaultFontID(defaultBoldFont);
通常、ユーザーがテキストを入力できる局面では、フォント選択ダイアログによってフォントを選択できるようにすべきです( 図 8.3 参照 )。
図 8.3 フォント選択ダイアログ
FontSelect 関数はフォント選択ダイアログを表示します。この関数は引数として FontID をとり、その値のフォントがダイアログの初期状態で選択されているようにします。この関数はユーザーが選択したフォントの FontID を返します。
newFontID = FontSelect(textFont);
デフォルトフォントは文字エンコーディングによって異なるため、フォント選択画面で選択されるフォントサイズもまた文字エンコーディングによって異なります。この理由により、最初の呼び出しでは FntGlueGetDefaultFontID によってシステムのデフォルトフォントを取得し、その復帰値を FontSelect に渡さなければなりません。以降の FontSelect コールでは、ユーザーがその時点で選択しているフォントを渡すことができます。
高密度ディスプレイ用のフォント
高密度ディスプレイフィーチャセットが存在する場合、Palm OS は低密度( 160 x 160 )と高密度( 320 x 320 )の両方の表示をサポートします。1.5x ディスプレイフィーチャセットは 320 x 240 ―― “1.5 倍密度”または 1.5x ―― の表示をサポートします。高密度ディスプレイは倍密度でも 1.5倍密度でも、より高い解像度を得るために同じスペースにたくさんのピクセルを詰め込みます。
複数の表示密度をサポートするために、Palm OS は拡張されたフォントリソースを使用します。拡張フォントリソースには、サポートされる各密度のための文字画像のセットが含まれています。Palm OS は実行時に表示密度を調べ、その表示密度に適した文字画像を使用してテキストを描画します。倍密度ディスプレイでは、テキストは倍密度の文字列画像を使用して描画されます。低密度ディスプレイではテキストは低密度の文字画像を使用して描画されます。
Palm OS は高密度ディスプレイフィーチャセットが存在する場合、組込みフォントのそれぞれについて拡張フォントリソースを保持します。アプリケーションがこれらのフォントだけを使用する場合、高密度ディスプレイではデフォルトで高密度フォントを使ってテキストが描画されます。高密度フォントを使うためにコードを変更する必要はまったくありません。
図 8.4 低密度フォントと高密度フォント
フォントの密度を考慮する必要が発生するのは、高密度スクリーンにおいて通常よりも多くのテキストを表示する必要がある場合( Palm OS Programmer's API Reference の WinSetScalingMode 関数の説明を参照して下さい )か、あるいはカスタムフォントを使用する場合だけです。
- カスタムフォントを作成する場合、拡張フォントリソースも作成したいと考えるでしょう。これについては“カスタムフォントの作成”を参照して下さい。拡張フォントリソースが利用できないか、あるいは倍密度の文字画像が含まれていない場合、Palm OS は低密度の文字画像をピクセルレベルで2倍して倍密度ディスプレイに描画します。
- オフスクリーンウィンドウにカスタムフォントを使ってテキストを描画する場合は注意が必要です。オフスクリーンウィンドウにもディスプレイ密度があるからです。低密度のオフスクリーンウィンドウを作成してテキストを描画する場合、低密度フォントまたは拡張フォントの低密度文字画像が使用されます。リソースに高密度の文字画像しか含まれていない場合、描画エンジンはフォントビットマップを縮小します。この結果、オフスクリーンウィンドウが高密度ディスプレイに転送されて拡大されると、低品質なテキストが表示されることになります。低密度フォントが利用できる場合、描画エンジンは最良の結果を得るために、ウィンドウへのテキスト描画において低密度フォントを代わりに使用します。Palm OS は組込みフォントに関しては低密度と高密度の両方のフォントを用意しているため、これはカスタムフォントを使用した場合だけの潜在的な問題です。
- WARNING!
- 描画エンジンには、倍密度データ( テキストあるいはビットマップ )を 1.5x へ、あるいは 1.5x のデータを倍密度へ描画する際の処理は定義されていません。ただし、低密度のフォントやビットマップを高密度の宛先( 1.5x または倍密度 )に描画する処理は期待どおりに動作します。
プログラムからのフォント設定
UI 要素がラベルやテキストコンテンツに使用するフォントを設定する場合、UI 要素によって異なる関数を使用します。表 8.3 に UI 要素別のフォント設定関数を示します。
表 8.3 フォントの設定
UI オブジェクト | 関数 |
---|---|
フィールド | FldSetFont |
テーブル内のフィールド | TblSetItemFont |
コマンドボタン,プッシュボタン,ポップアップトリガー,セレクタトリガー,チェックボックス | CtlGlueSetFont |
ラベルリソース | FrmGlueSetLabelFont |
リストの要素 | LstGlueSetFont |
その他のテキスト(スクリーンに直接描画されるテキスト | FntSetFont |
FntSetFont 関数はシステムがデフォルトで使用するフォントを変更します。この関数は直前まで設定されていたフォントを返します。FntSetFont が返却するフォントは保存しておき、作業が終了したらレストアすべきです。リスト 8.11 に、カスタムリスト描画関数でリスト要素を描画するフォントの設定例を示します。
リスト 8.11 プログラムでのフォント設定
void DrawOneRowInList(Int16 itemNum, RectangleType *bounds, Char **itemsText) { Boolean didSetFont = false; FontID oldFont; if( (itemNum % 5) == 0 ) { oldFont = FntSetFont(boldFont); didSetFont = true; } WinDrawChars( itemsText[itemNum], StrLen( itemsText[itemNum] ), bounds.topLeft.x, bounds.topLeft.y ); if( didSetFont ) FntSetFont( oldFont ); }
フォント情報の取得
フォントに関する情報と、それがどのようにスクリーンに描画されるのかを取得するには、フォントマネージャの関数を使用します。図 8.5 にフォントが持つ特徴を図解します。表 8.4 にフォントマネージャを使用して取得できる情報の種類を一覧します。
図 8.5 フォントの特徴
表 8.4 フォント情報の取得
特徴 | 関数 |
---|---|
Font hengit | FntCharHeight |
Ascent | FntBaseLine |
Descent | FntDescenderHeight |
Leading + font height | FntLineHeight |
Maximum width of a character in the font | FntAverageCharWidth |
Width of a specific character | FntWCharWidth(FntGlueWCharWidth) |
Character displayed at particular location | FntWidthToOffset(FntGlueWidthToOffset) |
表 8.4 に示した関数は全て、その時点で設定されているフォント ―― つまり、描画ステートにリストされているフォント ―― に対して働きます。フォントを変更するには FntSetFont を使用します。例えば、フィールド内のテキストに使用されるフォントの行高を知りたければ、以下のようにします。
リスト 8.12 フィールドフォントの特徴の取得
FieldType *fieldP; FontID oldFont; Int16 lineHeight; oldFont = FntSetFont(FldGetFont(fieldP)); lineHeight = FntLineHeight(); FntSetFont(oldFont);
カスタムフォントの作成
Palm OS 3.0 以降では、カスタムフォントの使用がサポートされています。独自のフォントリソース( 'NFNT' )を作成し、アプリケーションで使用することができます。
高密度ディスプレイフィーチャセットが存在している場合、かわりに拡張フォントリソース( 'nfnt' )を使用することもできます。拡張フォントリソースにはディスプレイ密度別にそれぞれの文字画像が含まれています。
フォントリソースと拡張フォントリソースは、ともに Palm Latin 文字エンコーディング( 256 文字 )をサポートするだけの大きさしかありません。それよりも大きな文字セットに対するカスタムフォントの定義はサポートされていません。
フォントリソースの作成
Palm OS SDK はカスタムフォントを作成するためのツールを提供していません。しかし、xFont や PilRC といったいくつかのサードパーティアプリケーションがカスタムフォントの作成に利用できます。
- TIP
- フォントの各文字画像の右端に、何も描画されない列を1列残しておいて下さい。Mac OS が描画した文字の右側を1ピクセル分クリアしてから次の文字を描画するのに対し、Palm OS は文字を詰めて描画します。作成するフォントがリーディング( leading )を必要とする場合、同様に文字画像の一番下に何も描画しないようにして下さい。これは、Palm OS ではリーディングがサポートされないからです。
拡張フォントリソースを作成するには、Constructor for Palm OS を使用します。
- フォントリソースを2つ、(xFont のような)サードパーティ製のツールを使用して作成します。2つめのフォントは1つめのフォントのちょうど2倍になっている必要があります。つまり、高さも幅も2倍ということです。
- Constructor for Palm OS を使用してフォントファミリを作成します。詳細は“Constructor for Palm OS”を参照して下さい。
- 1つめの 'NFNT' リソースを通常密度のフォントとして使用し、2つめの 'NFNT' リソースを倍密度フォントとして使用します。
PalmRez ポストリンカは、デバイスで使用される拡張フォントリソースをフォントファミリリソースから作成します。
アプリケーションにおけるカスタムフォントの使用
リソースファイルでカスタムフォントを定義したら、アプリケーションでそのフォントを使う前にフォント ID を割り当てなければなりません。フォント ID はフォントのリソース ID とは違います。これは 0 〜 255 の番号で、カスタムフォントに使用するのは fntAppFontCustomBase 以上の値です。それよりも小さな値はシステムによる使用のために予約されています。FntDefineFont 関数によってフォント ID をフォントリソースに割り当てます。フォントリソースは、フォントが使用されている間、ずっとロックされている必要があります。フォントリソースのロード、ロック、フォント ID の割り当てを全てアプリケーションの AppStart 関数で行うのがいいでしょう。フォントリソースのアンロックとリリースは AppStop 関数で行ないます。
リスト 8.13 に、フォントリソースをロードしてフォント ID を割り当て、新しいフォントを利用してスクリーンに文字列を描画するコードのサンプルを示します。
リスト 8.13 カスタムフォントのロードと使用
#define customFontID ((FontID) fntAppFontCustomBase) MemHandle customFontH; FontType *customFontP; Err AppStart(void) { ... // Load the font resource and assign it a font ID. customFontH = DmGetResource(fontRscType, MyCoolFontRscID); customFontP = (FontType *)MemHandleLock(customFontH); FntDefineFont(customFontID, customFontP); ... } void AppStop(void) { ... //Release the font resource when app quits. MemHandleUnlock(customFontH); DmReleaseResource(customFontH); ... } void DrawCharsInNewFont(void) { FontID oldFont = FntSetFont(customFontID); Char *msg = "Look, Mom. It’s a new font!"; WinDrawChars(msg, StrLen(msg), 28, 0); FntSetFont(oldFont); }
拡張フォントを使用するには、基本的に上記と同じコードを使用します。ただし、DmGetResource に渡すリソースタイプを fontExtRscType に変更しなければなりません。
customFontH = DmGetResource(fontExtRscType, MyCoolExtFontRscID); // rest as shown above.
拡張フォントにアクセスする場合でも FontType 構造体を指すポインタを使用していることに注意して下さい。
拡張フォントを構築するために作成した 'NFNT' リソースは、拡張フォントを作った後で破棄されてしまいます。下位互換性を維持するためには、カスタムフォントの低密度の文字画像を含む 'NFNT' リソースを別途定義する必要があります。
倍密度の文字画像だけで、低密度の文字画像を含まない拡張フォントリソースを作成することもできます。'NFNT' リソースとして低密度の文字画像を用意し、拡張フォントリソースは倍密度の文字画像だけを使用することも可能です。その場合、低密度スクリーンのハンドヘルド(高密度フィーチャセットをサポートしないものも含めて)では 'NFNT' リソースをロードして使用し、低密度でないディスプレイの場合は拡張フォントリソースを使用するのです。こうようにする場合、ロードするリソースを決める前に注意深くディスプレイの密度をチェックする必要があります( リスト 8.14 参照 )。
- WARNING!
- 低密度のオフスクリーンウィンドウに倍密度の文字画像を使ってテキストを描画した場合の挙動は定義されておらず、Palm OS がクラッシュする可能性があります。リスト 8.14 の方法でフォントをロードする場合、低密度のオフスクリーンウィンドウにテキストを描画する際には古いフォントリソースをロードして使用して下さい。詳細は“高密度ディスプレイ用のフォント”を参照して下さい。
リスト 8.14 条件付きでのフォントリソースのロード
#define customFontID ((FontID) fntAppFontCustomBase) MemHandle fontH = NULL; FontType *fontP; UInt16 winVersion; Err error; error = FtrGet(sysFtrCreator, sysFtrNumWinVersion, &winVersion); // If winVersion is >= 4, the high-density feature set // is present. Check what type of display we are on // and load the appropriate font resource. if (!error && (winVersion >= 4)) { UInt32 density; error = WinScreenGetAttribute(winScreenDensity, &density); if (!error && (density != kDensityLow)) { // load and use the extended font resource. fontH = DmGetResource(fontExtRscType, MyNewFontRscID); fontP = MemHandleLock(fontH); } } if (!fontH) { // Either the feature set is not present or we’re on a // low-density screen. Load and use the 'NFNT' resource. fontH = DmGetResource(fontRscType, MyOldFontRscID); fontP = (FontType *)MemHandleLock(fontH); } FntDefineFont(customFontID, fontP);