gtk-rs研究の続き。今回は、画像を重ねてみる。やりたいことは、こういう画像と:
こういう画像とを重ねて:
こういう表示をしたい。
複数の画像の描画は、前回の記事の方法でも行える。
drawingArea.connect_draw(move |widget, context| {
context.set_source_pixbuf(&pix1, 0f64, 0f64);
context.paint();
context.set_source_pixbuf(&pix2, 0f64, 0f64);
context.paint();
return Inhibit(false);
});
こんな感じで複数のPixbufを、set_source_pixbuf()してpaint()していけば良い。しかし、これだとdrawの度に描画が起きるため、数が増えていくとパフォーマンスに影響したり、ちらついたりするだろう。GTK+では、こういう時はSurfaceを使うようだ。
// Pixbuf(ト、ヘ音記号部分)
let clefpix = match Pixbuf::new_from_file("images/clefsImage.gif") {
Err(e) => {
println!("Err: {}.", e);
return;
}
Ok(p) => p
};
// Pixbuf(#記号)
let sharppix = match Pixbuf::new_from_file("images/sharp.gif") {
Err(e) => {
println!("Err: {}.", e);
return;
}
Ok(p) => p
};
// オフスクリーンバッファとして、ImageSurfaceを用意。
let isf = ImageSurface::create(Format::Rgb24, clefpix.get_width(), clefpix.get_height());
// Contextを生成して、
let ctx = Context::new(&isf);
// 描画
ctx.set_source_pixbuf(&clefpix, 0f64, 0f64);
ctx.paint();
ctx.set_source_pixbuf(&sharppix, 100f64, 100f64);
ctx.paint();
// 最後にflush()が必要のようだ。
isf.flush();
これで描画済のImageSurfaceが出来あがるので、drawの中では、これを描画すれば良い(ws.surfaceが上で作ったImageSurface)。
let ws = windowState.clone();
windowState.drawingArea.connect_draw(move |widget, context| {
context.set_source_surface(&ws.surface, 0f64, 0f64);
context.paint();
return Inhibit(false);
});
できた。
サンプルコード全体は、GitHubに置いておいた。