日記帳

日記です。

cairo graphics library on SDL

上のサンプルを書いてからメモリイメージに描画できるなら SDL*1SDL_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 で置き換えることも可能かもしれません?