BREW の文字列について知ろう ! - 2 / 2 -
ワイド文字のエンコード
ここでちょっと一休みをして、 AECHAR 型のエンコードについてお話します。重要なお話ではありませんから、気軽に読み流してください。 AECHAR 型に日本語を格納できることは理解できました。では、内部的には、AECHAR 型はどのような文字エンコードをもつのでしょうか。
AECHAR 型は実際には 16 ビット符号なし整数です。 16 ビットであることから Unicode (UTF-16) ではないかと推測される方がいるかもしれませんが、 Unicode ではありません(Unicode の場合もあるかもしれませんが)。
実は、 AECHAR 型がどのような文字エンコードをもつか (BREW によりどのようなエンコードとして解釈されるか)という問題は、携帯電話端末のエンコード(端末エンコード)に完全に依存しています。
日本語を表示できる携帯電話端末の場合、端末エンコードはたいていShift_JISですが、その場合、 AECHAR 型は Shift_JIS エンコードから派生したエンコードを持ちます。
「BREW API リファレンス」を開いて、 STREXPAND() 関数の説明をよく調べてみてください。次のように記述されています。
入力文字列をワイド文字に拡大します。 127 以下の文字は幅が 2 倍に拡大されます。
127 を超える文字は pDest にコピーされます。
つまり、 char 型に Shift_JIS エンコード文字列を指定して STREXPAND() を呼び出すと、 Shift_JIS のうち ASCII コードの文字は、そのコードが AECHAR 文字として格納され、マルチバイト文字は 2 バイトコードが AECHAR 文字として格納されます。
下の図を見ると、 AECHAR 文字列がどのようなエンコードをもつか、一目瞭然でしょう。
※半角カタカナは、 127 を超えるコードをもつにも関わらず、 ASCII 文字と同じように拡大されるようです(BREW エミュレータで確認)。したがって、「BREW API リファレンス」の STREXPAND() の説明は誤っているようです。
文字列の描画とフォント
BREW で文字列を描画する関数は IDISPLAY_DrawText() です。この関数は、指定されたフォントで、指定された四角形内に、文字列を描画します。中央揃え、右寄せ、などもできます。
ただひとつ、文字列の折り返し描画ができないのが不便な点です。後で、文字列の折り返し描画を行うアプレットを作成してみることにします。 IDISPLAY_DrawText() の関数プロトタイプは以下のようになります。
int IDISPLAY_DrawText ( IDisplay * pIDisplay, // IDisplay オブジェクト AEEFont Font, // フォント const AECHAR * pcText, // 描画する文字列 int nChars, // 描画する文字数 int x, // 左上X座標 int y, // 左上Y座標 const AEERect * prcBackground, // クリップする長方形 uint32 dwFlags // 右寄せなどのフラグ )
文字列を描画するには、フォントを指定する必要があります。フォントは AEEFont 型の定数で指定します。 BREW SDK 2.1 では以下の定数が用意されています。
typedef enum { AEE_FONT_NORMAL=0x8000, // 通常のフォント AEE_FONT_BOLD, // 太字のフォント AEE_FONT_LARGE, // 大きいフォント AEE_FONT_TOTAL // 使われていません (将来のための予約) } AEEFont;
もちろん、携帯電話端末でサポートされていなければ、 AEE_FONT_BOLD を指定したからといって必ずしも太いフォントになるわけではありませんし、 AEE_FONT_LARGE が必ず AEE_FONT_NORMAL より大きいサイズになるという保証はありません。実際の表示は携帯電話端末の仕様に依存します。
携帯電話の仕様に依存しない描画を行うには、それぞれのフォントのサイズを取得する必要があります。そのためには IDISPLAY_GetFontMetrics() 関数を使用します。
int IDISPLAY_GetFontMetrics ( IDisplay * pIDisplay, AEEFont Font, // フォントを指定する int * pnAscent, // フォントのアセントを取得する int * pnDescent // フォントのディセントを取得する )
フォントのアセントとかディセントについてご存知ない方は、「BREW API リファレンス」の AEEFontInfo の項目に解説がありますので、ご参照ください。とりあえず、フォントの高さは「アセント+ディセント」の値である、という理解で十分でしょう。
BREW のフォントには「フォントの幅」という情報はありませんが、特定のフォントで特定の文字列を描画したときの横幅を計算することはできます。これを計算するには、 IDISPLAY_MeasureText() または IDISPLAY_MeasureTextEx() 関数を使います。この関数の詳細は「BREW API リファレンス」をご参照ください。
※「BREW API リファレンス」には、フォントに関係する IFont というインターフェイスについて記述がありますが、 BREW アプリの開発者がこのインターフェイスを使用することはないと思われますので、知る必要はありません。
今回のサンプルアプリ
それでは、今回学んだ知識を元にして、四角形の中に長い文字列を改行しながら表示するアプレットを作成してみましょう(クリックで別ウィンドウにソースコード表示)。
記事掲載プログラムのソースコード
SophiaFramework UNIVERSE を使用して作成したソースコード
textwrap_sf.zip (SophiaFramework UNIVERSE 5.1)