Пример построения изображения василька на существующем и построенном в предыдущем уроке изображении.
Векторная библиотека позволяет работать с изображением в единичной декартовой системе координат (т.е. диапазон значений координат по осям X и Y находится в области от 0 до 1).
По нажатию на кнопку зададим графические примитивы, которые формируют картинку цветка. В качестве контекста устройства для отрисовки изображения получаем область для рисования с помощью функции gtk_widget_get_window(). Обратите внимание, в основной программе в качестве параметра data в функцию передается переменная-указатель на drawing_area (область рисования).
Функция cairo_scale() позволяет задать масштаб изображения и увеличить рисунок в заданное число раз по ширине и высоте.
#include <gtk/gtk.h> // подключаем GTK+ #include <cairo.h> // подключаем библиотеку векторной графики Cairo #include <math.h> // подключаем библиотеку математических функций и констант /* Функция, вызываемая на перерисовку содержимого окна */ void on_draw_event (GtkWidget *widget, cairo_t *cr, gpointer data) { /* Отрисовка неба */ cairo_set_source_rgb(cr, 0.0, 0.0, 1.0); cairo_rectangle(cr, 0, 0, 700, 300); cairo_fill(cr); /* Отрисовка земли */ cairo_set_source_rgb(cr, 0.3, 0.3, 0.0); cairo_rectangle(cr, 0, 300, 700, 200); cairo_fill(cr); /* Отрисовка солнца */ cairo_set_source_rgb(cr, 1, 1, 0.0); cairo_arc(cr, 500, 0, 50, 0, M_PI); cairo_fill(cr); /* Отрисовка лучей */ cairo_move_to(cr, 500, 0); cairo_line_to(cr, 400, 50); cairo_move_to(cr, 500, 0); cairo_line_to(cr, 500, 100); cairo_move_to(cr, 500, 0); cairo_line_to(cr, 600, 50); cairo_stroke(cr); } /* Функция, вызываемая на событие нажатия кнопки */ void button_click (GtkButton *button, gpointer data) { cairo_t *cr; cr = gdk_cairo_create(gtk_widget_get_window(data)); /* Масштабирование изображения по X и Y */ cairo_scale(cr, 400, 400); /* Отрисовка стебля */ cairo_set_line_width (cr, 0.01); cairo_set_source_rgb(cr, 0.0, 1.0, 0.0); cairo_move_to (cr, 0.4, 0.4); cairo_curve_to (cr, 0.7, 0.5, 0.4, 0.9, 0.7, 0.9); cairo_stroke(cr); /* Отрисовка листика */ cairo_arc(cr, 0.75, 0.7, 0.2, M_PI, 2*M_PI - M_PI_4); cairo_fill(cr); /* Отрисовка лепестков */ cairo_set_source_rgb(cr, 0.3, 0.8, 0.8); cairo_move_to(cr, 0.2, 0.1); cairo_line_to(cr, 0.5, 0.0); cairo_line_to(cr, 0.4, 0.4); cairo_close_path(cr); cairo_fill(cr); cairo_move_to(cr, 0.7, 0.1); cairo_line_to(cr, 0.8, 0.4); cairo_line_to(cr, 0.4, 0.4); cairo_close_path(cr); cairo_fill(cr); cairo_move_to(cr, 0.0, 0.3); cairo_line_to(cr, 0.4, 0.4); cairo_line_to(cr, 0.3, 0.7); cairo_close_path(cr); cairo_fill(cr); /* Отрисовка сердцевины */ cairo_set_source_rgb(cr, 1, 1, 0.0); cairo_arc(cr, 0.4, 0.4, 0.1, 0, 2 * M_PI); cairo_fill(cr); } /* Основная функция с которой стартует выполнение программы */ int main( int argc, char *argv[]) { /* запустить GTK+ */ gtk_init(&argc, &argv); /* создать новый виджет - окно и установить свойства*/ GtkWidget *window; window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 650, 500); gtk_window_set_title(GTK_WINDOW(window), "Sun"); gtk_container_set_border_width (GTK_CONTAINER (window), 10); /* Событие, которое отрабатывает на закрытие окна */ g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); /* создать виджет - вертикального расположения элементов */ GtkWidget *vbox; vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1); gtk_container_add(GTK_CONTAINER (window), vbox); /* создать виджет - область для рисования */ GtkWidget *drawing_area; drawing_area = gtk_drawing_area_new(); /* разместить область в верхней части окна*/ gtk_box_pack_start (GTK_BOX(vbox), drawing_area, TRUE, TRUE, 10); /* Событие отрисовки содержимого области */ g_signal_connect(G_OBJECT(drawing_area), "draw", G_CALLBACK(on_draw_event), NULL); /* создать виджет - кнопка */ GtkWidget *button; button = gtk_button_new_with_label("Draw"); gtk_container_set_border_width (GTK_CONTAINER (button), 10); /* разместить кнопку в нижней части окна*/ gtk_box_pack_end (GTK_BOX(vbox), button, FALSE, FALSE, 10); /* Событие, которое отрабатывает на нажатие кнопки, в качестве параметра передана область для рисования */ g_signal_connect(GTK_BUTTON(button), "clicked", G_CALLBACK(button_click), drawing_area); /* отобразить окно и все его виджеты */ gtk_widget_show_all(window); /* передаём управление GTK+ */ gtk_main(); return 0; }