cairo を使ったクロスプラットフォーム・グラフィックス

一貫した出力の生成を目指すベクトル描画ライブラリー

cairo はプリンターと画面の両方でまったく同じ出力を、しかもプラットフォームに依存しない方法で生成することにこだわって作成されました。そんな cairo は、Linux® グラフィックスの世界で中心的な存在となってきています。GNOME、GTK+、Pango やその他多くで使用されている 2D の威力を活用してください。

Eli Dow, Software Engineer, IBM Linux Test and Integration Center

Eli Dowは、ニューヨーク州Poughkeepsieにある、IBM Linux Test and Integration Centerのソフトウェア技術者です。Clarkson Universityにて、コンピューター・サイエンスおよび心理学で学位を、またコンピューター・サイエンスで修士を取得しています。彼が関心を持っている領域は、GNOMEデスクトップや、人とコンピューターの対話動作、Linuxシステム・プログラミングなどです。連絡先はemdow@us.ibm.comです。



2007年 9月 05日

cairo の利点と用途

cairo は複数の出力フォーマットへの描画が可能なベクトル描画ライブラリーで、フリー・ソフトウェアとして提供されています。cairo はLinux、BSD、Microsoft® Windows®、OSX をはじめとするさまざまなプラットフォームをサポートします (BeOS および OS2 バックエンドをサポートしたものも開発中です)。Linux 描画は X Window システム、Quartz、イメージ・バッファー形式、または OpenGL のコンテキストなどにより実行することができます。さらに cairo では、グラフィックスを PostScript または PDF 出力にレンダリングして高品質の印刷結果を得ることも可能です。理想的には、cairo を使用すれば印刷と画面との出力をほとんど同一にすることができます。

この記事では cairo とは何か、そしてなぜ、cairo がアプリケーションで役立つのかを説明します。ここに記載する例は、IBM ロゴのバージョンを表示する pdf、ps、png、svg、gtk のウィンドウを生成します。

cairo での設計上の重要な決定は、可能な限り同一の出力をサポートするということです。一貫した出力は、GUI ツールキットのプログラミングやクロスプラットフォームのアプリケーション開発に格別に適したものとなります。高解像度で画面を出力できること、そして画面のコンテンツを同じ描画ライブラリーで描画できるということは明らかな利点です。

さらに、cairo はサポートするターゲットそれぞれで、ベースとなるハードウェアおよびソフトウェアのサポートをインテリジェントに利用しようと試みます。このような高品質のベクトル・グラフィックスとハイパフォーマンスの組み合わせが、cairo を最新の UNIX® 描画システムの代表格としてふわさしいものにしています。

cairo は C 言語で作成されていますが、よく使われる言語に対応したバインディングもあります。C 言語を選択したことが、新しいバインディングを作成する際に役立っていると同時に、それぞれの言語から起動した場合の高いパフォーマンスを実現する上でも貢献しています。なかでも特筆するに値するのは Python バインディングです。このバインディングによって、迅速なプロトタイピングが可能になるだけでなく、cairo を初めて使う人でも cairo の描画 API を容易に理解できるようになっています。

ベクトル描画とビットマップ描画の違い

cairo はベクトル描画ライブラリーなので、その描画はビットマップに埋め込まれたピクセルのシーケンスではなく、代数的な記述を中心としています。ビットマップ描画では、一連のピクセルに事前に決められた色の値が事前に決められた配置で入力されるため、描画の品質はビットマップのサイズに比例することになります。

ビットマップ方式の描画では、ビットマップ画像をズームインまたは拡大するとビットマップ画像が正しい表示をしなくなります。画像が「ファジー」、つまりぼやけて見えて、リアプロジェクション・テレビやその他の大型テレビに近づいていったときと同じような現象になることがよくあります。遠くからは鮮明に見える画像でも、近づいて見ると個々の点の連なりになってしまうのです。これは明らかな定義の欠如で、ズームインまたは拡大によって、事前定義されたピクセル間の関係を定義するデータが存在できなくなってしまうことが原因となっています。

コンピューターの描画システムとアーキテクチャーはだいぶ前から登場しています。cairo がその設計において大いに参考にしているのは初期の PostScript および PDF モデルです。PostScript と PDF (Portable Document Format) はいずれも数学的記述を使って画像を定義していることから、cairo はこの 2 つの手法をモデル化しました。画像を代数で表せば、対象範囲の代数的記述を評価することによって常に画像全体あるいは画像の一部分だけを再現できるからです。代数的性質は、点、曲線、線として表現されます (この 3 つはベクトルを構成するため、ベクトル描画と名付けられています)。

計算を再評価して画像やそのコンポーネントを再描画できるため、画像をズーム、拡大、あるいは変換しても解像度は落ちません。ただし、ベクトル描画には限界もあります。例えば、実際には必要とされることのないような極めて高いズーム値までベクトル画像を拡大すると、問題が発生することがあります。その問題とは、ズームインすると計算の丸め誤差により一部の線が誤って表示されたり、ズームアウトすると特定の線が表示または認識されないというような問題です。

cairo 描画のベクトル性には、ベクトル画像はサイズが小さくなる傾向があるというさらなる利点もあります。その理由は、比較的大量の情報でも比較的小さな方程式にエンコードできるからです。また、描画が比較的単純化されるのもベクトル描画の利点です。点、線、そしてそれぞれに関連付けられた方程式を実際に変換して可視化するという作業は、描画ライブラリーが行ってくれます。

これらの曲線を記述する方程式は、数学者ピエール・ベジェ (Pierre Bezier) にちなんでベジェ曲線またはベジェ・パスと呼ばれています。ベジェ曲線は最小 2 つのアンカー・ポイント、そしてハンドルと呼ばれるアンカー・ポイント間の 1 つ以上の点で構成されます。ハンドル・ポイントを移動すると曲線の形状を変えられます。Photoshop や GIMP などのツールを使用したことがあれば、このようなタイプの曲線を扱った経験もあると思いますが、最終的に保存した描画のフォーマットはビットマップだったはずです。ファイルのフォーマットによって、ベジェ・パスの情報が維持されるか、あるいは特定の範囲で評価されてビットマップとして保存されるかが決まります。

この記事を書いている時点で入手可能な cairo バインディングには、C++、Ruby、Perl、Java™ 言語、Net/mono などがあります。バインディングごとに開発の完成度は異なるので、それぞれのバインディングについての詳細の最新情報は cairo プロジェクトのホーム・ページ (リンクを「参考文献」に記載) を参照してください。現在オープン・ソース・コミュニティー全体で最も広範に使用されているのは、Python および C++ バインディングのようです。

前述したように、複数のグラフィックス・ツールキットが cairo 開発をさらに容易にするバインディングを提供しています。バージョン 2.8 より新しい Gtk+ には cairo が完全にサポートされています。これはつまり、今後の GTK リリースをサポートする戦略的描画システムとして cairo が抜擢されたということです。さらに、GNUstep や FLTK などのツールキットでも、グラフィックス・レンダリングのニーズに対応するために cairo をサポートし始めています。

描画演算や合成を細かく制御しなければならないクロスプラットフォームのアプリケーションを計画している場合、cairo を描画 API として選択する完璧な理由となります。クロスプラットフォーム機能が必要な一方、下位レベルでの描画を必要としない場合には、cairo をベースとした便利な描画ライブラリーがあります。


新しい画像処理モデルを学ぶ理由とは

率直に言って、既存のオープン・ソース・ソリューションはさまざまな意味で不十分だと思います。xprint には表示用と印刷用の API が統一されているという利点がありますが、通常は別個のサーバー・プロセスとして実行するように構成されるため、API が充実していません。また、libgnomeprint では印刷モデルと画像処理モデルを分けていますが、印刷 API とr画像処理 API を別々にすると、画面とプリンターでのレンダリングに差が出てしまいます。

これまでの画像処理モデルから教訓を得た cairo は、完全な共通 API を実装するように設計されています。


cairo のレンダリング対象

cairo でレンダリングできる出力フォーマットは以下のとおりです。

  • X Window System (RENDER 拡張を使用可能な場合は Render 拡張を利用)
  • OpenGL (glitz バックエンドを利用)
  • メモリー内の画像 (pixbuff など)
  • PostScript (印刷する場合に適切)
  • PDF (Portable Document Format) ファイル
  • SVG (Scalable Vector Graphics) フォーマット

ただし、上記のレンダリング対象がすべて同等に作成されるわけではありません。cairo は各種のバックエンドでまったく同じ出力を作成することを目指していますが、バックエンドにはそれぞれ固有の利点があります。例えば、PDF バックエンドは可能な場合にはベクトル・ベースとなる一方 (必要な場合にのみ画像に戻ります)、PostScript バックエンドは本質的にページごとに大きな 1 つの画像を生成します。

cairo のレンダリング・モデルは、多くの既存の技術による影響を受けています。cairo にはパス、ストローク、フィルという PostScript の概念があり、実装しているのは PDF と最新の X サーバー実装のRENDER 拡張からなる Porter-Duff 画像です。さらに cairo はクリッピング、マスク、グラディエントという通常の補完機能も実装しています。


cairo アプリケーションの具体例

多数の有力なオープン・ソース・プロジェクトが cairo を採り入れたことにより、cairo は Linux グラフィックスの世界で重要な役割を占めるようになっています。すでに cairo を採用している代表的なプロジェクトには以下のものがあります。

  • Gtk+。万人に好まれているクロスプラットフォーム・グラフィックス・ツールキットです。
  • Pango。テキストのレイアウトおよびレンダリング用のフリー・ソフトウェア・ライブラリーで、国際化対応に重点を置いています。
  • Gnome。フリー・ソフトウェアによるデスクトップ環境です。
  • Mozilla。Firefox がベースとするクロスプラットフォーム Web ブラウザー・インフラストラクチャーです。
  • OpenOffice.org。Microsoft Office に匹敵するフリー・ソフトウェアのオフィス・スイートです。

cairo での概念的描画

cairo を使って描画する場合、その最も単純な操作は、媒体を決め、絵筆を取り、色を選び、線の配置を考え、そして実際に線を描くようなものです。cairo のプロジェクト・チームはその資料のなかで画家を例として使っているので、ここでは私もそれに倣って説明することにします。

画家にとって通常最も簡単なのは、まっさらな媒体を選ぶことです。現実の世界では紙、布、あるいは壁を選ぶアーティストもいるかもしれませんが、cairo でも同じく空白の媒体を選択しなければなりません。空白の媒体に描画する際には、cairo のコンテキスト、つまり主題を設定する必要があります。このコンテキストからは、PostScript ファイル、PDF 文書、または画面上の画像など、対象となる面 (描画先) を選択することができます。このようにして、何にペイントするかを選択します。

画家の次のタスクとなるのは、絵筆の選択です。画家は適切な絵筆の先端とサイズとを選ぶのにかなりの時間をかけることがありますが、cairo でもこの絵筆の先端という概念があります。それを表すのがストローク幅です。ストローク幅の違いによって線の太さが変わってきます。

現実の世界でペイントするアーティストとは異なり、cairo のユーザーには正確な座標という観点が必要です。アーティストは絵筆を紙に置くだけかもしれませんが、コンピューターがデジタル・ペイントを行う位置を認識するには x 座標と y 座標が必要になります。

cairo に絵筆と描画の開始位置を設定したら、次にストロークがどのように表示されるかを想像します。単純な描画としては直線が考えられますが、(実際のアーティストと同じように) 自由に曲線や弧を描くこともできます。

そして最後に定義するのが、ストロークを終了する位置です。この場合も同じく、(x,y) 座標のペアを使って位置を指定します。

さらに、描画したオブジェクトに「色を塗る」こともできます。cairo の用語では、これをフィルと呼びます。cairo には、上記で説明した操作のそれぞれに単純に対応した API 実装があります。そのうちの初歩的な API については次のセクションで説明します。

これらの基本操作は、極めて複雑なグラフィックスを作成するのにも役立ちます。cairo では、例えば既に描画してあるオブジェクトにズームインする操作に相当する変換や、描画オブジェクトを仮想紙の別の場所に移動する操作に相当する変換を適用するなど、画家が簡単にできないようなことでも実行することができます。

GIMP や Photoshop でもこのような操作の多くを実行できますが、cairo はそれとは別だということに注意してください。cairo はプログラムによって作品を作り上げる手段です。一方、GIMP と Photoshop は cairo のようなツールを「表面下で」使って描画を実行します。これらのツールによる描画では、マウスが自動的に座標点とツールのタイプ (ボックスなど) を設定し、GUI 環境を介してペンとストロークを自動的に選択してくれます。サンプル・コード (「ダウンロード」を参照) を見るとわかるように、cairo にはそれよりも明示的な対話、例えば「ストローク幅 1 を使用し、z 位置を中心点とした半径 10 の弧を設定する」などのような命令が必要です。


適切な cairo 用語

どんな技術について話すときでも常に重要なことは、正しい用語を使うことです。cairo の API 用語は、中核となる描画用語、面用語、そしてフォント関連の用語という 3 つのカテゴリーに分けられます (詳細は「参考文献」を参照)。

何よりもまず、cairo には描画コンテキストがあります。これは前述の例えで言うと、キャンバス上での画家の描画の動きに似たものです。コンテキストは cairo_t というタイプになっており、描画をレンダリングするために必要となります。このようなコンテキストで一般的に実行することは、ベジェの形状、線および曲線のレンダリングです。曲線を成す一連の形状とそれに関連付けられたデータは、cairo 用語ではパスと呼ばれます。パスには、描画した後にストロークまたは塗りつぶしを設定することができます。

座標は至って単純な API を使ってパスに変換されます。この API が優れているわけは、線形代数やグラフィックスについての講座や教科書で通常取り上げられる複雑な変換マトリックスの種類を考える必要がなくなることです。cairo での描画操作の変換はあらゆるアフィン変換を使って実行することができます。これらのアフィン変換は、描画したオブジェクト全体あるいはその一部をシアー (傾斜) させたり、拡大または回転するためのツールになります。それぞれのパスは、点を指定することで描画されます。このように、cairo は点と点を結ぶという方法で動作します。その一例は後で記載します。

次に取り上げるのは、さまざまな cairo の面のタイプです。cairo の面は数種類あり、それぞれが特定の描画の対象となる出力にマッピングされています。cairo のとは、描画対象のことです。具体的に言うと、画像 (メモリー内バッファー) に対応する面、glitz を利用した Open GL 面、文書をレンダリングするための PDF および PostScript 面、そして XLib や Win32 を介した直接プラットフォーム描画用の面があります。これらの面のそれぞれは基本の面タイプ、cairo_surface_t から派生したものです。

cairo におけるパターンは読み取り可能な対象で、つまり描画操作のソースまたはマスクとして使用されるものです。cairo でのパターンは、ソリッド、面ベース、さらにはグラディエント・パターンにすることもできます。

ここまでのところで説明したのはパスのストロークについてのみです。しかしパスのストロークは通常、面白みのない線を描画するだけです。事実、単純な線のストロークは cairo での 5 つの基本的な描画操作のひとつに過ぎません。この 5 つの操作とは次のとおりです。

  • cairo_stroke
  • cairo_fill
  • cairo_show_text/cairo_show_glyphs
  • cairo_paint
  • cairo_mask

単純な線の描画はもちろん使い勝手が良いですが、線の描画ではフォントのような複雑なものは表現しきれません。そこで cairo に備わっているのが、フォント用の基本クラス、cairo_font_face_t です。cairo は特定フォント・サイズのキャッシュ・メトリックが含まれる拡大/縮小フォントを認識し、さらに各種のフォント・オプションで特定のフォントをレンダリングする方法も指定できます。cairo を操作するときに使用するフォントは一般に、UNIX では Freetype フォント、Windows プラットフォームでは Win32 フォントです。


cairo のサンプル・アプリケーション

cairo を使用して IBM ロゴをペイントするちょっとしたコードを作成してみました。このコードは、以下の「ダウンロード」セクションからダウンロードすることができます。このコードを実行すると、以下の出力が作成されるはずです。

cairo で作成した IBM ロゴ
cairo で作成した IBM ロゴ

このコードでは、cairo_stroke (cr) の行に注目してください。私は文字を描画した後、「登録商標」マークを追加する前にこの行を入れています。cairo はストロークがなければ何も描画しません。ストロークを含めるのをうっかり忘れてしまうのは、初心者にありがちなことです。


今でも進化を続ける cairo

cairo のリリース・バージョンは、Linux カーネル・リリースと同じようなパターンとなっています。つまり、奇数番号のリリースは試験的な開発バージョンなので、自信のない人や実動環境を管理する人向きではありません。偶数番号のリリースには改良が加えられています。最初の 1.0 リリースで重点が置かれたのはユーザーに使いやすい API にすること、そして高品質の出力にすることでした。そして 1.2 リリースの API では十分に開発されているとは言えないバックエンドを完成させることに焦点が絞られ、現行の 1.4 シリーズでは最適化および新しい機能に大幅な進展を見せています。

cairo の開発者たちは、cairo API のさまざまな機能を示すサンプル・コード・スニペットをいくつか用意しています (これらのサンプル・プログラムへのリンクは、以下の「参考文献」セクションに記載しています)。次の cairo のバージョンがリリースされるまで待つことはありません。現行バージョンをダウンロードして早速試してみてください。


ダウンロード

内容ファイル名サイズ
Cairo code to draw IBM logocairo-example.tar20KB

参考文献

学ぶために

製品や技術を入手するために

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux
ArticleID=259362
ArticleTitle=cairo を使ったクロスプラットフォーム・グラフィックス
publish-date=09052007