In this part of the Cairo graphics programming tutorial, we will define compositing operations
There are several compositing operations.
The cairo graphics library has 14 different compositing operations.
compositing.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #include <cairo.h>
#include <gtk/gtk.h>
static void draw(cairo_t *cr, gint x, gint w, gint h, cairo_operator_t op);
static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data);
int main(int argc, char *argv[]){
GtkWidget *window;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "expose-event", G_CALLBACK(on_expose_event), NULL);
g_signal_connect(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), 510, 120);
gtk_window_set_title(GTK_WINDOW(window), "compositing operations");
gtk_widget_set_app_paintable(window, TRUE);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
static void draw(cairo_t *cr, gint x, gint w, gint h, cairo_operator_t op){
cairo_t *first_cr, *second_cr;
cairo_surface_t *first, *second;
/*
we create two surfaces
*/
first = cairo_surface_create_similar(cairo_get_target(cr), CAIRO_CONTENT_COLOR_ALPHA, w, h);
second = cairo_surface_create_similar(cairo_get_target(cr), CAIRO_CONTENT_COLOR_ALPHA, w, h);
/* we draw a rectangle into the surface */
first_cr = cairo_create(first);
cairo_set_source_rgb(first_cr, 0, 0, 0.4);
cairo_rectangle(first_cr, x, 20, 50, 50);
cairo_fill(first_cr);
second_cr = cairo_create(second);
cairo_set_source_rgb(second_cr, 0.5, 0.5, 0);
cairo_rectangle(second_cr, x+10, 40, 50, 50);
cairo_fill(second_cr);
/*
we apply the compositing operation on the surfaces
*/
cairo_set_operator(first_cr, op);
cairo_set_source_surface(first_cr, second, 0, 0);
cairo_paint(first_cr);
/*
finally we draw the outcome onto the GTK+ window
*/
cairo_set_source_surface(cr, first, 0, 0);
cairo_paint(cr);
cairo_surface_destroy(first);
cairo_surface_destroy(second);
cairo_destroy(first_cr);
cairo_destroy(second_cr);
}
static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data){
cairo_t *cr;
gint w, h;
gint x, y;
/*
in our example, we use these six compositing operations.
*/
cairo_operator_t oper[] = {
CAIRO_OPERATOR_DEST_OVER,
CAIRO_OPERATOR_DEST_IN,
CAIRO_OPERATOR_OUT,
CAIRO_OPERATOR_ADD,
CAIRO_OPERATOR_ATOP,
CAIRO_OPERATOR_DEST_ATOP
};
gtk_window_get_size(GTK_WINDOW(widget), &w, &h);
cr = gdk_cairo_create(widget->window);
gint i;
for(x = 20, y= 20, i = 0; i < 6; x += 80, i++){
draw(cr, x, w, h, oper[i]);
}
cairo_destroy(cr);
return FALSE;
}
|
compositing.c の実行結果は: