在这一篇中讲述裁剪(Clipping)与遮蔽(Masking)。
裁剪
在下面的示例中,对一幅图像进行裁剪。
#include <cairo.h>
#include <gtk/gtk.h>
#include <math.h>
cairo_surface_t *image;
staticgboolean
on_expose_event(GtkWidget *widget,
GdkEventExpose *event,
gpointer data)
{
cairo_t *cr;
staticgint pos_x = 128;
staticgint pos_y = 128;
gint radius = 40;
staticgint delta[] = { 3, 3 };
cr = gdk_cairo_create(widget->window);
gint width, height;
gtk_window_get_size(GTK_WINDOW(widget), &width, &height);
if(pos_x < 0 + radius) {
delta[0] =rand() % 4 + 5;
}else if (pos_x > width - radius) {
delta[0] = -(rand() % 4 + 5);
}
if(pos_y < 0 + radius) {
delta[1] =rand() % 4 + 5;
}else if (pos_y > height - radius) {
delta[1] = -(rand() % 4 + 5);
}
pos_x += delta[0];
pos_y += delta[1];
cairo_set_source_surface(cr, image, 1, 1);
cairo_arc(cr, pos_x, pos_y, radius, 0, 2*M_PI);
cairo_clip(cr);
cairo_paint(cr);
cairo_destroy(cr);
returnFALSE;
}
staticgboolean
time_handler (GtkWidget *widget)
{
if(widget->window == NULL) returnFALSE;
gtk_widget_queue_draw(widget);
returnTRUE;
}
int main(int argc,char *argv[])
{
GtkWidget *window;
gint width, height;
image = cairo_image_surface_create_from_png("turnacastle.png");
width = cairo_image_surface_get_width(image);
height = cairo_image_surface_get_height(image);
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(window),"expose-event",
G_CALLBACK(on_expose_event), NULL);
g_signal_connect(G_OBJECT(window),"destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), width+2, height+2);
gtk_widget_set_app_paintable(window, TRUE);
gtk_widget_show_all(window);
g_timeout_add(100, (GSourceFunc) time_handler, (gpointer) window);
gtk_main();
cairo_surface_destroy(image);
return0;
在这一示例中,在窗口中会有一个圆形区域不断移动,并且在该区域显示位于其下的图像,仿佛是通过一个孔洞观看图像。
if
(pos_x < 0 + radius) {
|