絵の描画

2010年2月11日

ファイル

22-draw.tar.gz

内容

線や矩形などを描画してみましょう。ここでは、描画はウインドウに対して直接に行わず、代りにバックグラウンドの描画領域に対して行い、ウインドウの再描画要求に応じてバックグラウンドの描画領域をウインドウの描画領域に描画する、という手順で実装します。

描画領域として、GtkDrawingArea を使います。

	drawingArea = gtk_drawing_area_new();

gtk_widget_set_size_request() で描画領域のサイズを指定します。

	gtk_widget_set_size_request(drawingArea, WIDTH, HEIGHT);

コールバック関数の設定を行います。

	g_signal_connect(drawingArea,
	  "configure-event", G_CALLBACK(configure), NULL);
	g_signal_connect(drawingArea,
	  "expose-event", G_CALLBACK(draw), NULL);

"configure-event" はサイズが変更されたときなどに発生します。"expose-event" は再描画要求です。"configure-event" でバックグラウンドの描画領域を作成して描画を行い、"expose-event" でバックグラウンドの描画領域をウインドウの描画領域に描画します。

"configure-event" のコールバック関数内で、バックグラウンドの描画領域 GdkPixmap を作ります。

	if(pixmap) g_object_unref(pixmap);

	pixmap = gdk_pixmap_new(
	  drawingArea->window,
	  drawingArea->allocation.width,
	  drawingArea->allocation.height,
	  -1
	);

実際の描画領域と同じ大きさのものを作ります。もし作成済みであったら、先に参照をはずします。

背景を白で塗りつぶします。

	gdk_draw_rectangle(
	  pixmap,
	  drawingArea->style->white_gc,
	  TRUE,
	  0, 0,
	  drawingArea->allocation.width,
	  drawingArea->allocation.height
	);

gdk_draw_rectangle() は、矩形を描画します。drawingArea->style->white_gc は白の "グラフィックコンテキスト" です。グラフィックコンテキストとは、色や線の太さなどの設定のセットです。第 3 引数では、矩形の中を塗りつぶすかどうかを指定します。残りの引数は、矩形の左上端のウインドウ座標と矩形の幅、高さを指定します。

グラフィックコンテキストを取得します。

	gc = drawingArea->style->fg_gc[GTK_WIDGET_STATE(drawingArea)];

前景色を指定します。

	gdk_color_parse("#000000", &color);
	gdk_gc_set_rgb_fg_color(gc, &color);

gdk_color_parse() では 16 進数で色を指定できます。

gdk_gc_set_line_attributes() で線の属性を指定します。

	gdk_gc_set_line_attributes(
	  gc,
	  1,
	  GDK_LINE_SOLID,
	  GDK_CAP_NOT_LAST,
	  GDK_JOIN_MITER
	);

第 2 引数は線の太さです。第 3 引数に GDK_LINE_ON_OFF_DASH を指定すると、線が点線になります。

gdk_draw_point() で、指定した座標に点を打ちます。

	for(i = 0; i < HEIGHT; i += 10){
		gdk_draw_point(
		  pixmap,
		  gc,
		  10, i
		);
	}

gdk_draw_line() で、指定した始点・終点を結ぶ線を引きます。

	for(i = 0; i < 60; i += 20){
		gdk_draw_line(
		  pixmap,
		  drawingArea->style->black_gc,
		  20, 20 + i,
		  100, 50 - i
		);
	}

drawingArea->style->black_gc は黒のグラフィックコンテキストです。

gdk_draw_rectangle() の第 3 引数に FALSE を渡すと、線で矩形が描かれます。

	gdk_draw_rectangle(
	  pixmap,
	  gc,
	  FALSE,
	  50, 90,
	  100, 50
	);

gdk_draw_arc() で円弧を描くことができます。

	gdk_draw_arc(
	  pixmap,
	  gc,
	  TRUE,
	  70, 180,
	  100, 100,
	  0, 120*64
	);

第 3 引数は塗りつぶしの指定です。第 4 〜 7 引数で円弧の境界の矩形領域を指定し、第 8, 9 引数で角度の視点・終点を指定しています。角度は 1/64 度単位なので、120 度を指定したい場合は 120*64 を入力します。

gdk_draw_polygon() で多角形を描くことができます。

	gdk_draw_polygon(
	  pixmap,
	  gc,
	  FALSE,
	  points,
	  5
	);

第 3 引数は塗りつぶしの指定、第 4 引数は GdkPoint の配列、第 5 引数は点の数です。

テキストの描画には PangoLayout を使います。PangoLayout は次のように作ります。

	layout = gtk_widget_create_pango_layout(drawingArea, NULL);

フォントの指定には PangoFontDescription を使います。

	fontDesc = pango_font_description_from_string("MS Gothic 18");
	pango_layout_set_font_description(layout, fontDesc);

layout にテキストを設定し、gdk_draw_layout() でテキストを描画します。

	pango_layout_set_text(layout, "Text", -1);
	gdk_draw_layout(pixmap, gc, 230, 130, layout);

"expose-event" のコールバック関数で、以下のように、バックグラウンドの描画領域 (pixmap) をウインドウの描画領域 (drawingArea) に描画します。

void draw(GtkWidget *drawingArea, GdkEventExpose *event, gpointer data)
{
	gdk_draw_drawable(
	  drawingArea->window,
	  drawingArea->style->fg_gc[GTK_WIDGET_STATE(drawingArea)],
	  pixmap,
	  event->area.x, event->area.y,
	  event->area.x, event->area.y,
	  event->area.width, event->area.height
	);
}

GTK+ プログラミング 目次へ