前回はテキスト描画用APIとしてDrawThemeTextBox()を紹介しました。筆者も、最近までこのAPIを便利に使っていましたが、自作アプリケーションをMac OS X 10.5(Leoperd)へ対応させる作業(さらなるモダン化)で幾つかの問題点に遭遇しました。今回からは、そのお話をします。
Mac OS X 10.5で正式採用されるだろう(多分)機能の中に「レゾリューション・インディペンデント」と言うものがあります。これは、モニタ側のレゾリューションが何DPIであろうとも、そこに表示されるメニュー、ウィンドウ、コントロールなどのUIは、アプリケーション開発者やユーザの好みに合わせて解像度が調整できるという機能です。例えば、640x480ピクセルのウィンドウを30インチ・シネマディスプレーの画面いっぱいに表示しても、その美しさが損なわれない仕組みが提供されるわけです。
確かに現状(Mac OS X 10.4)でも、30インチシネマディスプレーの解像度を640X480ピクセルに設定し、同サイズのウィンドウをオープンすれば画面いっぱいに表示されます。しかし、UIやその中の文字列に関しては単純にビットマップ拡大されるだけで、かなりぼやけた感じとなり、決して美しい表示とは言えません。「レゾリューション・インディペンデント」機能に対応させたアプリケーションであれば、UIで表示している文字や画像はくっきり・はっきり美しく表示させることが可能となります。
筆者は歯科用データベースを開発しているのですが、ユーザから「データ入力や表示画面を大きなモニタになるべくいっぱいに表示したい(患者さんにプレゼンするにもその方が効果的)」という要望をしばしばもらいます。現状、30インチなどの大型ディスプレーを使うと、そこに表示される文字が小さすぎて操作し難いケースが多々あります。特に、私のような老眼のシニアには辛いものがあるわけです(笑)。「レゾリューション・インディペンデント」が当たり前になれば、こうした不平不満の大部分が解消されるでしょうから、Mac OS X 10.5から導入されるこの機能には大きな期待を持っています。
ちまたではあまり知られていませんが、この機能、Mac OS X 10.4(Tiger)から導入準備が開始されています。具体例を上げてみましょう。まず、Interface Builder(v2.5.4)からNibファイルに登録されているウィンドウ・オブジェクトを選択し、Toolsメニューの「Show Inspector」で情報を表示をします。上部ポップアップメニューで「Attributes」を選択すると、そのウィンドウに関する各種アトリビュートを設定できるのですが、上から4番目に「Scaling:」というポップアップメニューがあるのが分かります。実は「レゾリューション・インディペンデント」に対応したウィンドウかどうかは、このメニューにより設定できるようになっています。
「Scaling:」メニューから「Framework Scaled」を選択してNibファイルを保存し、自作アプリケーションからそのウィンドウをオープンしてやります。通常であれば、いつもとまったく代わり映えしないウィンドウがオープンします。そこで一旦アプリケーションを終了し、「Xcode Tools」をインストールすると一緒に保存される「Quartz Debug」というアプリケーションを起動します。このアプリケーションの保存場所は以下の通りです。
/Developer/Applications/Performance Tools/Quartz Debug
Quartz DebugのToolsメニューから「Show User Interface Resolution」を選択すると、倍率を変更するためのコントロールウィンドウがオープンします。例えば倍率を1.5に設定して再度自作アプリケーションを起動し、先ほどFramework Scaledアトリビュートを設定したウィンドウをオープンすると、今度は前回よりサイズが1.5倍の大きいウィンドウとして表示されることになります。この倍率設定は、Quartz Debugを終了するまで継続されています。
Mac OS X 10.4では「レゾリューション・インディペンデント」機能の実装は不完全であり表示のバグも多い(多すぎる)ので、倍率指定したUIを完全な状態で表示することはできません。しかし、その雰囲気は十分に味わうことはできます。ちなみに、この機能に対応させるためには、描画用APIにも幾つかの制限があります。ウィンドウやコントロールなど、システム側で描画を受け持つオブジェクトは問題ないのですが、QuickDraw APIでの自前描画処理は、この機能にまったく対応していません。つまり、その部分だけ「レゾリューション・インディペンデント」で表示されないのです。
前振りが長くなりましたが、実は前回紹介したDrawThemeTextBox()によるテキスト描画は、今まで説明してきた「レゾリューション・インディペンデント」に対応していません。API自体はDEPRECATED指定ではないですし、描画環境はCoreGraphicsのCGContextRefで指示できるのですが、描画処理の方はQuickDrawに大きく依存しているもようです。ひょっとして、正式版の10.5ではOKになるかもしれませんが、現時点ではそれも不透明ですので、将来を見据えて更にモダンなテキスト描画APIを探した方が良さそうです。
そこで、またまたヘッダファイルのジャングルをさまよい歩いた結果(笑)、HITheme.hで以下のようなAPIを発見しました。このAPIを用いたテキスト描画は、間違いなく「レゾリューション・インディペンデント」に対応しているもようです。例えば、テキスト描画矩形領域もRect構造体ではなく、CoreGraphicsのHIRect構造体指定であり、QuickDraw環境から完全に脱却していることが理解できます。

描画させたい文字列はCFStringRefで指定し、描画対象はCGContextRefで指定します。また描画方法の詳細については、以下のHIThemeTextInfo構造体で指示するようになっています。最後のHIThemeOrientationにより、描画原点を左上か左下のどちらかに設定できます。通常、CoreGraphics環境では左下原点ですが、ウィンドウに表示するコントロール(HIView)等は左上原点ですので、どちらの描画原点にも対応できるよう考慮されているようです。

HIThemeDrawTextBox()は、Compositing指定されたウィンドウやコントロール(HIView)のテキスト描画を担当していると考えられます。次回は、上記HIThemeTextInfo構造体の内容をさらに詳しく調べ、このAPIを用いたテキスト描画にチャレンジしてみたいと思います。