Hatena::ブログ(Diary)

日記帳 このページをアンテナに追加 RSSフィード

 | 

2006-01-13

cairo graphics library

| 00:53 |  cairo graphics libraryを含むブックマーク

cairo をというライブラリを使ってみました.

cairo は様々なバックエンド上に2Dベクターグラフィックスを描画するAPIを提供してくれます.cairo がサポートしているバックエンドは以下の通りです.

応用例としてはいまのところ以下のものくらいでしょうか?

  • FirefoxSVG サポートのバックエンド
  • GNU classpath*1 の Graphics2D クラス

このライブラリを以前から試してみようと思いつつ今一つ気が乗らず放置していました.理由は cairo 自体が Window の初期化やイベント処理などのAPIを持たない,純粋なグラフィックス描画のための API であり,Win32 API や Xlib,GTK+といったOS依存のライブラリと組合せて使うものだからです.マルチプラットホーム大好きっことしてはOS依存のコードが入るかと思うとモチベーションが下ってしまうのですね…


最初の一歩

とりあえず Window を表示するのは X や Win32 の初期化が必要になって面倒なのでオンメモリに描画して PNG ファイルに保存するサンプルを動かします.

http://cairographics.org/FAQ の Getting Started の項目の例を参考にして以下のようなコードを書いてみました.

hw.c

#include <cairo.h>
int
main (int argc, char *argv[])
{
	cairo_surface_t *surface;
	cairo_t *cr;

	surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 300, 200);
	cr = cairo_create (surface);

	cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
	cairo_rectangle(cr, 0, 0, 300, 200);
	cairo_fill(cr);

	cairo_select_font_face (cr, "Serif", CAIRO_FONT_SLANT_NORMAL,
		CAIRO_FONT_WEIGHT_BOLD);
	cairo_set_font_size (cr, 32.0);
	cairo_set_source_rgba (cr, 0.0, 0.3, 1.0, 1.0);
	cairo_move_to (cr, 10.0, 50.0);
	cairo_show_text (cr, "Hello World");
	cairo_move_to (cr, 10.0, 100.0);
	cairo_show_text (cr, "こんにちは世界");

	cairo_destroy (cr);
	cairo_surface_write_to_png (surface, "hw.png");
	cairo_surface_destroy (surface);

	return 0;
}

ファイルのエンコーディングをUTF8にして保存.コンパイルは以下の通り.

% gcc -o hw hw.c `pkg-config --cflags --libs cairo`

実行すると hw.png というファイルが生成されてちゃんと日本語文字列も描画されています.

cairo graphics library on SDL

| 00:53 |  cairo graphics library on SDLを含むブックマーク

上のサンプルを書いてからメモリイメージに描画できるなら SDL*2の SDL_Surface にも描画できるんじゃないかしら?と思って試してみました.

hello_on_SDL.c

#include <cairo.h>
#include <SDL.h>
#include <stdlib.h>

#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480

int
main (int argc, char *argv[])
{
	SDL_bool done;
	SDL_Surface* screen;
	cairo_surface_t *surface;
	cairo_t *cr;

	/* init SDL system and screen surface */
	SDL_Init(SDL_INIT_VIDEO);
	atexit(SDL_Quit);
	screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT,
		32, SDL_SWSURFACE);

	/* init cairo surface and cairo drawing context */
	surface = cairo_image_surface_create_for_data (screen->pixels,
		CAIRO_FORMAT_ARGB32, SCREEN_WIDTH, SCREEN_HEIGHT, screen->pitch);
	cr = cairo_create (surface);

	/* fill bg */
	cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
	cairo_rectangle(cr, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
	cairo_fill(cr);

	/* draw text */
	cairo_select_font_face (cr, "Serif", CAIRO_FONT_SLANT_NORMAL,
		CAIRO_FONT_WEIGHT_BOLD);
	cairo_set_font_size (cr, 32.0);
	cairo_set_source_rgba (cr, 0.0, 0.3, 1.0, 1.0);
	cairo_move_to (cr, 10.0, 50.0);
	cairo_show_text (cr, "Hello World");
	cairo_move_to (cr, 10.0, 100.0);
	cairo_show_text (cr, "こんにちは世界");

	SDL_Flip(screen);

	/* event loop */
	done = SDL_FALSE;
	while (!done)
	{
		SDL_Event event;
		SDL_WaitEvent(&event);
		switch (event.type)
		{
		case SDL_QUIT :
			done = SDL_TRUE;
			break;
		case SDL_KEYDOWN :
			if (event.key.keysym.sym == SDLK_q ||
				event.key.keysym.sym == SDLK_ESCAPE )
			{
				done = SDL_TRUE;
			}
			break;
		default:
			break;
		}
	}

	/* finalize cairo surface and cairo drawing context */
	cairo_destroy (cr);
	cairo_surface_destroy (surface);

	exit(0);
	return 0;
}

コンパイルは以下の通り.

% gcc -o hello_on_SDL hello_on_SDL.c `pkg-config --cflags --libs cairo` `sdl-config --cflags --libs `

実行すると期待通り動きました.あっさりと.

これが動くってことは cairo の描画 API を使ったマルチプラットホームなアプリケーションが簡単に作れそうですね.これまで SDL の 2D描画(OpenGLなしの描画)で SDL_ttf や SDL_gfx が担ってきた部分を cairo で置き換えることも可能かもしれません?

トラックバック - http://d.hatena.ne.jp/sa-y/20060113
 | 
2005 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 10 | 12 |
2007 | 01 | 02 | 03 | 06 | 07 | 08 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 |
2009 | 01 | 02 | 04 | 05 | 06 | 08 | 10 | 12 |
2010 | 01 | 02 | 03 | 04 | 07 | 08 | 09 | 10 | 12 |
2011 | 01 | 03 | 06 | 12 |
2013 | 01 | 08 | 11 |
ページビュー
199097