タイトル小池邦人のプログラミング日記》2001/10/30<Quartz 2D(Core Graphics)を使う その6>カテゴリーグラフィックス, 小池邦人のプログラミング日記
作成日2001/10/30 17:16:6作成者新居雅行
Mac OS X 10.1ではQuartz 2Dについてもいくらか機能拡張がなされているようです。まずは、10.0.4では使えなかった機能が正常になったかどうかを調べ、続いて、これまで詳しく言及してこなかった描画機能や、10.1で新しく追加された機能について順次解説していこうと思います。

10/30現在、ADCメンバーサイトには「CarebonLib_1.5d7_SDK」が登録されています。今回は、Mac OS 9やMac OS Xの新バージョンの発表が間近に控えていないためか、SDKのバージョンの進み具合にも余裕を感じます(笑)。以前には、β版の若い番号から2階級特進で突然GM版が登場したこともありましたが、今回はd版のまま着実に数字が進んでいるようです。SDKに含まれているRelease Notesを読むと、DataBrowserコントロールやMLTE(Multilingual Text Engine)など、いつもより大量のバグフィックスや改良点がリストアップされています。これもスケジュールに余裕がある証拠でしょうか?ちなみに、Mac OS X 10.1に搭載されているCarebonLibも未だに1.4です。Apple社は早急かつ確実にCarebonLib 1.5を完成させ、我々デベロッパーに安心してCarbonアプリケーションを開発できる環境を提供して欲しいと思います。

それから、以下のサイトに登録されているQuartz 2Dに関するドキュメントも、久しぶりにアップデートされました。

◇Quartz 2D
 http://developer.apple.com/techpubs/macosx/CoreTechnologies/graphics/Quartz2D/quartz2d.html

ひとつは、以前から登録されていた「Drawing With Quartz 2D」です。ページ数が10ページ程度増え、10.0.4では対応していなかったPattern描画機能などについても言及されています。Quartz 2DのPatternに関するAPI定義は「CGPattern.h」にまとめられています。このヘッダーファイルはUniversal Interfaces 3.4.1b2には含まれておらず、CarebonLib 1.5d7 SDKに添付されている3.4.1b3の方に含まれていますので、定義内容を参照したい方は注意してください。もうひとつは、新規に登録された「Quartz 2D Preliminary API Reference」という200ページ程度のドキュメントです。こちらは、Quartz 2D APIの機能、引数の意味、返り値などを、すべて解説したリファレンスです。これでもう、ヘッダーファイルを検索してAPIの引数内容を調べるといった作業も減るでしょう。喜ばしいことです。

また、パソコン関連の書籍を大量に扱っている書店で、以前にAdobeサイトに登録されていることを紹介した「PDF Reference Version 1.3 2nd Ed.」の和訳本を見つけてしまいました。「PDFリファレンス 第2版」(株)ピアソン・エデュケーション(6,800円)です。

Quartz 2DはPDFの仕様とほぼ一致する描画機能を持つため、描画に用いるカラースペース、座標システム、変換座標、レンダリング方法、図形のポイント入力方法などの多くの「概念」はPDFから引き継いでいます。ですから、この書籍を参照しながら「Drawing With Quartz 2D」を読めば、より理解が深まると思います(こちらは日本語ですし)。ちょっと高価なのが玉に瑕ですが、興味がある方は購入されてみてはいかがでしょうか?

さて、Quartz 2DをMac OS X 10.0.4で利用している時に2つの大きな問題があったことを思い出してください。ひとつは、オフスクリーンとして用意したGWroldを、Quartz 2D Contextに設定できないという問題でした。CreateCGContextForPort()にNewGWrold()で得たGWorldPtrを渡しても、「パラメータが異常」というエラーが返ってきてContextが得られませんでした。もうひとつは、CGBitmapContextCreate()を使い、QuickDraw PixMapをContextに設定する場合の不都合です。このAPIの5番目の引数「bytesPerRow」の値は、きっちりwidth(矩形の幅)x4 Byteでないと受け付けられませんでした。そのため、10.0.4でオフスクリーンをContextに設定する時には、以下のような回りくどい方法を取っていました。

 

これらの不都合が直っているかどうかをMac OS X 10.1環境で調べてみたところ、結果として、両問題点ともちゃんと解消されていました。これにより、オフスクリーン用のGWroldをContextに設定する時には、以下のような単純なルーチンを用意するだけでOKになったわけです。

 

続いて、Quartz 2Dを利用したテキスト描画を行ってみます。例えば、QuickDrawのDrawString()に準じるQuartz 2DのAPIはCGContextShowTextAtPoint()です。テキスト表示の開始座標(x,y)と文字列(Cストリングス)、そして文字列の長さを代入することで、指定されたContextにテキストを描画します。この時の表示は自動的にアンチエイリアス処理されます。フォントの種類やサイズはCGContextSelectFont()により設定します。同じく描画モード(スタイル)はCGContextSetTextDrawingMode()で設定できます。描画モードは、ヘッダーファイルのCGContext.hに8種類ほど定義されています。

 

ただし、この中にはクリッピング用のモードもありますので、すべてがテキストスタイルを変更するわけではありません。以下のルーチンは、こうしたAPIを利用することでウィンドウに5種類のテキストを描画しています。

 

ただし、Quartz 2Dでは簡単なテキスト描画しかサポートしておらず、複雑なレイアウトを必要とするような描画については、MLTEやATUSUIのAPIを利用するのが普通です。

実際にこのルーチンを実行した結果は以下のようになります。

 

最初に12ポイントと64ポイントのテキストを描画しています(kCGTextFillモード)。アンチエイリアス処理を比較するために、どちらにも上にQuickDrawのDrawString()で描画したテキストを列べてみました。また12ポイントのテキスト部分を拡大してみると以下のようになります。

 

上がQuickDrawによるアンチエイリアス処理で、下がQuartz 2Dによる処理です。この比較で両方のアンチエイリアス処理のアルゴリズムが微妙に異なるのが分かると思います。CocoaアプリとCarbonアプリで、テキスト表示に微妙な差がある事を気づかれた方も多いかもしれません。その原因はここにあったわけです。上から3番目の描画モードは、kCGTextStrokeで文字枠だけを描画しています。その下の描画モードはkCGTextFillStrokeで、加えてCGContextSetRGBFillColor()でRGBカラーを指定して内部を赤色で塗りつぶしています。最後のテキストは、CTM(座標変換用マトリックス)をいじることで、ミラー反転させた状態で描画を行っています。このような座標変換を利用したテキスト描画(回転などもそう)は、QuickDrawではマネの出来ない芸当です。

Quartz 2Dでは、こうしたテキスト描画でも一般の図形描画と何ら変わらず、ちゃんとPath(パス)が作られています。このPathに対して色々な指定をすれば、クリッピングによりテキスト内をPatternで埋めるようなことも可能となります。次回は、こうしたPathの特性を使い描画のクリッピングなどにチャレンジしてみる予定です。
[小池邦人/オッティモ]
関連リンクオッティモ