TGWS>プログラミング>VC2008でCairo>

VC2008でCairoを使う

このページには行き当たりばったりな表現が含まれます。
まとまった記事を期待する方は閲覧にご注意ください。

CairoってVCで使えるのか

さて、わたくし、急にSVGを自分のプログラムで表示してみたくなりまして、Cairoならそれができると聞きました。
なので、とりあえずCairoの最新バージョン(現時点で1.8.6)をインストールしてみました。
releasesのページから最新版にあたるcairo-1.8.6.tar.gzを落としてきて展開します。

うちはWindowsだからREADME.win32を読めばいいのかな…。
うちはWindowsだからREADME.win32を読めばいいのかな…。

とりあえずWindows環境の人向けっぽいREADME.win32があったので読んでみます。
Tools requiredとか、Libraries requiredとか、いろいろ書かれてます。

Tools required
==============
You will need GNU make, version 3.80 or later. Earlier versions or
other modern make implementations may work, but are not guaranteed to.

You will also need Microsoft Visual C++. Version 7 has been most
heavily tested, but other versions are likely to work fine.

Libraries required
==================
Cairo requires a compatible version of the pixman library. Full build
instructions are beyond the scope of this document; however, using the
same tools, it should be possible to build pixman simply by entering
the pixman/src directory and typing:

make -f Makefile.win32 CFG=release

Depending on your feature set, you may also need zlib and libpng.
(README.win32から引用)

なんかめんどくさそうだってことだけはわかった!
がんばれば何とかなるような方法が書いてあるんでしょうが、私は努力を知らない人間なのでもっと簡単に何とかなりそうな方法を探してみます。

cairommを試してみる

C++へのバインディングとして、cairommがあるそうなのでそれを試してみます(これを書いてる時点ではバインディングの意味が分かってません)。
現時点の最新版は1.8.0だから本家よりはちょっと遅れてるのかな?
なんて憶測を勝手に立てながらまた落としてきます。

いかにもそれらしいフォルダがあった!
いかにもそれらしいフォルダがあった!

展開してみると、MSVC_Net2008なんてフォルダがありました。
私が今もっているのはVC2005ですが、せっかくなので最新版に乗り換えてしまいます。
Microsoft Visual C++ 2008 Express Editionをインストールしましたが、その手順は今回関係ないので省略します。
そんでもって、MSVC_Net2008フォルダにあったREADMEを読んでみます。

* Install the latest Win32 GTK+ Development files from ftp://ftp.gnome.org/pub/GNOME/binaries/win32/gtk+/ and add the paths to headers and import libraries to Visual Studio (MSVC_Net2008/READMEから引用)

前と比べると圧倒的にシンプルです。
GTK+の最新版を落としてきてパス通すだけでいいみたいです。

ドレにパス通せばいいんスか…。
ドレにパス通せばいいんスか…。

なんかそれっぽいフォルダがいっぱいあってよくわかりません。
そんなときは、cairommがどのファイルを使っているのが調べてみましょう。

#include <vector>
#include <utility>
#include <cairomm/surface.h>
#include <cairomm/fontface.h>
#include <cairomm/matrix.h>
#include <cairomm/pattern.h>
#include <cairomm/path.h>
#include <cairomm/scaledfont.h>
#include <cairomm/types.h>
#include <valarray>
#include <vector>
#include <cairo.h>
(cairomm/context.hから引用)

…cairo.hって、どう見てもcairommのファイルじゃありませんよね。
cairommのフォルダ見てもそんなファイルありませんでしたもん。
そーですか。バインディングってそーゆー意味でしたか。知らない私がバカでしたよ。
つまり、すでにあるCairoをC++のやり方で使えるようにするための橋渡しをするのがcairommってわけです。
冷静に考えれば展開先フォルダ直下のREADMEファイルに明記してありましたよ。

This library provides a C++ interface to cairo.
(READMEから引用)

やっぱり普通のCairoを入れてみる

さりとて努力を放棄したのをその日のうちに撤回するなんてのも嫌です。
一番楽なのは前例に倣うことなので、Googleさんに聞いてみましょう(→「cairo vc」で検索)。
で、これを書いてる今現在トップに出てくるページは「2008-10-08 - やまざきの「あせらず、くさらず、一歩づつ」」でした。
どうやらWindows用のGTK+の「all-in-one bundle」をダウンロードするといいそうです。
これは盲点でした。個別に入れるのが面倒なら全部入れてしまえとは!
ちゃんとCairoの最新版も入っているようなので安心です。

Cairoも分かりやすい場所にあっていい感じ。
Cairoも分かりやすい場所にあっていい感じ。

とりあえずVC2008のオプションでパス通しときます。
たぶんCairo単体よりもGTK+全体にパスを通したほうがいいと思います。

実行可能ファイル(GTK+のディレクトリ)\bin
インクルードファイル(GTK+のディレクトリ)\include
ライブラリファイル(GTK+のディレクトリ)\lib

さて、ここまでできたところで、いよいよVCで動かしてみるわけですが…
実はcairommのあのそれっぽいプロジェクトがビルドできなかったんですね。
ファイルが足りないらしいんですけどね、それがどこにある何のファイルかというのが分からないんですね。
まだ何か足りないのは確実ですが、Cairoを普通にインストールしてしまった以上、いちいちcairommを使う必然性も感じません。
今後はC言語用のCairoをVC++で使っていくことにします。

フォームアプリケーションで使ってみる

結論から言うと、ダメでした。
例によって原因を詳しく調べるのは放棄します。

Win32アプリケーションで使ってみる

まず、Win32プロジェクトをデフォルトの新規作成します。
そしてcairo-win32.hをインクルードします。
cairo.libをリンクする必要もあるのでその指定もしています。

#include "stdafx.h"
#include "CairoTest2.h"
#include <cairo/cairo-win32.h>
#pragma comment(lib, "cairo.lib")
(CairoTest2.cpp)

で、今回はウィンドウの再描画のタイミングで描画することにしたので、WndProcのWM_PAINTメッセージの処理をいじってみます。

case WM_PAINT:
	hdc = BeginPaint(hWnd, &ps);

	OnPaint(hdc);

	EndPaint(hWnd, &ps);
	break;
(CairoTest2.cpp)

とりあえずWndProc関数内がごちゃごちゃになると嫌なのでOnPaint関数を作ってそちらで処理することにしました。

void OnPaint(HDC hdc)
{
	// サーフェスと描画コンテキストを生成
	cairo_surface_t* surface = cairo_win32_surface_create(hdc);
	cairo_t* cr = cairo_create(surface);

	// TODO: ここに実際の描画命令を入れる

	// サーフェスと描画コンテキストを破棄
	cairo_destroy(cr);
	cairo_surface_destroy(surface);
}
(CairoTest2.cpp)

TODOの部分にサンプルコードを入れるとそれぞれ対応したものが描かれます。
cairo_***_surface_create関数でサーフェス(絵を描くキャンバスみたいなもの?)を作って、cairo_create関数で取得したcairo_t*を使って描画するという流れになるようですね。
今回は、ウィンドウ上に描くのでcairo_win32_surface_createを使い、TODOの部分には最初のサンプルを入れました。

ちゃんと扇形が描画されました。
ちゃんと扇形が描画されました。

ほとんどサンプル通りとはいえ、なかなかいい具合です。
よく見るとちゃんとアンチエイリアスもかかっています。
ちなみに、こうやってできたプログラムを実行するには、以下の3つのDLLが必要になります。

無かった場合、エラーが出て起動できないのでEXEファイルと同じフォルダにコピーしておきましょう。
たぶんcairo-features.hをいじればいくつかは必要なくなると思うのですが、そこまでは今は調べていません。

今回使ったCPPファイル

まとめ

  1. Cairoはベクターグラフィックを扱える
  2. インストールするときはWindows用のGTK+の「all-in-one bundle」をダウンロードすると楽
  3. ビルドするときはcairo.libをリンクする
  4. 実行時はlibcairo-2.dll、libpng12-0.dll、zlib1.dllを実行ファイルと同じフォルダに入れて置く
  5. SVGの表示はまた機会があれば…