Cairoを入れてみる

今回の本命はこの Cairo Graphics Library でがす。MozillaSVGサポートにも利用されていますが…(ちなみに Mozilla.org の人が Cairo な人たちに MPL を維持するようにお願いしているあたりのメーリングリストのログはなかなか熱い感じでグーです)
CairoとSDLでプラットフォームに(あまり)依存しない画像描画環境を整えようというのが本筋。
(1) ご本家へれっつらごー。http://cairographics.org/introduction
(2) "Download" から "relases" というリンクを見つけて(判りにくい)クリック。本日ただいまの最新版は "cairo-1.0.2.tar.gz" なので、これをMSYSのホームディレクトリにダウンロード。
(3) MSYSを起動して、cairoの tar ball を解凍し、出来上がったディレクトリに移動。

$ tar xvzf cairo-1.0.2.tar.gz && cd cairo-1.0.2

(4) configureを実行。

$ ./confugre 
(..中略..)

cairo will be compiled with the following surface backends:
  Xlib: no (requires Xrender http://freedesktop.org/Software/xlibs)
  Quartz: no
  XCB: no
  Win32: yes
  PostScript: no (requires zlib http://www.gzip.org/zlib/)
  PDF: no
  glitz: no

the following font backends:
  FreeType: no
  Win32: yes
  ATSUI: no

and the following features:
  PNG functions: no

ふむふむ、PNGのサポートが死んでますね。必要そうなものを持ってきます。
(5) 再び MinGW のダウンロードページから、以下をダウンロード:

  • wget-1.9.1.tar.gz
  • wget-1.9.1-mingwPORT.tar.bz2
  • libpng-1.2.8-mingwPORT.tar.bz2
  • zlib-1.2.3-mingwPORT.tar.bz2

なんか SDL のポートもありますが…見なかったことに。バージョンも古いし。
(6) まず wget から行きましょう。

$ mv wget-1.9.1.tar.gz /tmp/ ; mkdir /usr/src
$ tar xvjf wget-1.9.1-mingwPORT.tar.bz2 && cd wget-1.9.1/mingwPORT && ./mingwPORT.sh

コツがいくつか…

  • wget-1.9.1.tar.gzは /tmp に置いておく。というか、どうも全部そこに置くのがデフォルトっぽいですね。
  • /usr/src というディレクトリを作っておく。ソースファイルはここに解凍されるっぽいです。
  • 最初の "Download file?"には "no" と答える。次の "Unarchived file?" は "yes"、あとは[ENTER]で。

これで wget がインストール完了。他の mingwPORT はこいつを使って tar ball をダウンロードしてきます。
(7) zlib 行ってみましょう。

$ tar xvjf zlib-1.2.3-mingwPORT.tar.bz2 && cd zlib-1.2.3/mingwPORT && ./mingwPORT.sh

んでもって[ENTER]を押しまくります。
(8) libpng も同じなんですが…

$ tar xvjf zlib-1.2.3-mingwPORT.tar.bz2 && cd zlib-1.2.3/mingwPORT && ./mingwPORT.sh
(..中略..)
Download file? (Yes) 
Download file URI? (http://download.sourceforge.net/libpng) http://jaist.dl.sourceforge.net/sourceforge/libpng 
(..後略..)

という感じで SourceForge のミラーを直接指定してやる必要があります。ここではJAISTサーバを直接指示しています。
(9) さてはて、やっとこ cairo に再チャレンジです。

$ ./confugre 
(..中略..)

cairo will be compiled with the following surface backends:
  Xlib: no (requires Xrender http://freedesktop.org/Software/xlibs)
  Quartz: no
  XCB: no
  Win32: yes
  PostScript: no (requires zlib http://www.gzip.org/zlib/)
  PDF: no
  glitz: no

the following font backends:
  FreeType: no
  Win32: yes
  ATSUI: no

and the following features:
  PNG functions: no

…駄目じゃん。
えーとpkg-configでこけてるんですね。
ざっくり探したけども MSYS 用の pkg-config は見つからず。
Gimp for Windows用のpkg-configを使うのがセオリーっぽいけど、ここでは敢えて棘の道を行くことにして、「俺pkg-config」をこさえて、/--exists.*libpng12*/ に真を返すようにしときます。

$ cat $HOME/my-pkg-config
#!/bin/sh

cmd=""
pkg=""

while [ "x$1" != "x" ]
do
	case $1 in
	--exists)
		cmd="$1 $cmd"
		;;
	--*)
		cmd="$cmd$1 "
		;;
	libpng12*)
		pkg=$1
		;;
	*)
		cmd="$cmd$1 "
		;;
	esac
	shift
done

case $cmd in
--exists*)
	case $pkg in
	libpng12*)
		exit 0
		;;
	*)
		exit 1
		;;
	esac
	;;
--atleast-pkgconfig-version*)
	exit 0;
	;;
  *)
	case $pkg in
	libpng12*)
		libpng12-config $cmd
		;;
	*)
		exit 1
		;;
	esac
esac
$ env PKG_CONFIG=$HOME/my-pkg-config ./configure
(..中略..)

cairo will be compiled with the following surface backends:
  Xlib: no (requires Xrender http://freedesktop.org/Software/xlibs)
  Quartz: no
  XCB: no
  Win32: yes
  PostScript: no
  PDF: no
  glitz: no

the following font backends:
  FreeType: no
  Win32: yes
  ATSUI: no

and the following features:
  PNG functions: yes

よしよし。

PDF や PostScript をイネーブルするには fontconfig と freetype が必要です。 freetypeMinGWのサイトからmingwPORTがダウンロードできますが、いろいろやらないと./configureが反応してくれません*1。まあ、fontconfigが無いので、どのみちビルド段階でこけます。
どうしてもという場合は gnuwin32 の力を借りるようです:http://lists.freedesktop.org/archives/cairo/2004-October/002110.html
…が、今日のところは諦めておきます。

(10) make && make install する。
その前に、もひとつパッチを当てます。

$ cat src.cairo-win32-surface.c.patch
*** src/cairo-win32-surface.c.orig	Sun Nov 13 23:28:46 2005
--- src/cairo-win32-surface.c	Sun Nov 13 23:28:46 2005
*************** static const cairo_surface_backend_t cai
*** 1062,1067 ****
--- 1062,1068 ----
  CRITICAL_SECTION cairo_toy_font_face_hash_table_mutex;
  CRITICAL_SECTION cairo_scaled_font_map_mutex;
  CRITICAL_SECTION cairo_ft_unscaled_font_map_mutex;
+ CRITICAL_SECTION _global_image_glyph_cache_mutex;
  
  BOOL WINAPI
  DllMain (HINSTANCE hinstDLL,
*************** DllMain (HINSTANCE hinstDLL,
*** 1075,1085 ****
--- 1076,1088 ----
      InitializeCriticalSection (&cairo_toy_font_face_hash_table_mutex);
      InitializeCriticalSection (&cairo_scaled_font_map_mutex);
      InitializeCriticalSection (&cairo_ft_unscaled_font_map_mutex);
+     InitializeCriticalSection (&_global_image_glyph_cache_mutex);
      break;
    case DLL_PROCESS_DETACH:
      DeleteCriticalSection (&cairo_toy_font_face_hash_table_mutex);
      DeleteCriticalSection (&cairo_scaled_font_map_mutex);
      DeleteCriticalSection (&cairo_ft_unscaled_font_map_mutex);
+     DeleteCriticalSection (&_global_image_glyph_cache_mutex);
      break;
    }
    return TRUE;
$ patch -p 0 < src.cairo-win32-surface.c.patch

ちなみに元ねたはこのあたりです:http://article.gmane.org/gmane.comp.lib.cairo/5350
さてはて、これでやっとこビルドできます。

あー疲れた…。

*1:configureのFT_Load_Sfnt_Tableのテストプログラムにtttables.hをインクルードし、さらにfreetype-configをいじれば通る。ただ、なぜ元のconfigureで駄目なのか判ってないのでお勧めしない…