|
|
Строка 1: |
Строка 1: |
- | In this part of the Cairo graphics programming tutorial, we will define compositing operations.
| |
| | | |
- | <b>Compositing</b> is the combining of visual elements from separate sources into single images.
| |
- | They are used to create the illusion that all those elements are parts of the same scene.
| |
- | Compositing is videly used in film industry to create crowds, entire new worlds which would be expensive or impossible to create otherwise. (wikipedia.org)
| |
- |
| |
- | == Operations ==
| |
- |
| |
- | There are several compositing operations. The Cairo graphics library has 14 different compositing operations.
| |
- |
| |
- | <source lang="cpp">
| |
- | #include <cairo.h>
| |
- | #include <gtk/gtk.h>
| |
- |
| |
- |
| |
- | 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;
| |
- |
| |
- | 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);
| |
- |
| |
- | 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);
| |
- |
| |
- | cairo_set_operator(first_cr, op);
| |
- | cairo_set_source_surface(first_cr, second, 0, 0);
| |
- | cairo_paint(first_cr);
| |
- |
| |
- | 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;
| |
- |
| |
- | 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;
| |
- | }
| |
- |
| |
- |
| |
- | 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_widget_set_app_paintable(window, TRUE);
| |
- |
| |
- | gtk_widget_show_all(window);
| |
- |
| |
- | gtk_main();
| |
- |
| |
- | return 0;
| |
- | }
| |
- | </source>
| |
- |
| |
- | In our example, we will show 6 different compositing operations on two squares.
| |
- |
| |
- | <source lang="cpp">
| |
- | 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);
| |
- |
| |
- | </source>
| |
- |
| |
- | We create two surfaces.
| |
- |
| |
- | <source lang="cpp">
| |
- | 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);
| |
- | </source>
| |
- |
| |
- | We draw a rectangle into the surface.
| |
- |
| |
- | <source lang="cpp">
| |
- | cairo_set_operator(first_cr, op);
| |
- | cairo_set_source_surface(first_cr, second, 0, 0);
| |
- | cairo_paint(first_cr);
| |
- |
| |
- | </source>
| |
- |
| |
- | We apply the compositing operation on the surfaces.
| |
- |
| |
- | <source lang="cpp">
| |
- | cairo_set_source_surface(cr, first, 0, 0);
| |
- | cairo_paint(cr);
| |
- | </source>
| |
- |
| |
- | Finally we draw the outcome onto the GTK+ window.
| |
- |
| |
- | <source lang="cpp">
| |
- | 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,
| |
- | };
| |
- | </source>
| |
- |
| |
- | In our example, we use these six compositing operations.
| |
- |
| |
- | [[image: cairo_faq_compositing.png | center]]
| |
- |
| |
- | [[Категория:GTK+]]
| |
- | [[Категория:Cairo]]
| |