How to rotate image using GTK+ / Cairo
c, cairo, gtk
Solution
You need to store the rotation in a variable and put the cairo_rotate(cr, rotation_amt); call into the on_expose_event method, before paint.
Also translate to the center of the window, rotate, and translate back, to make the wheel rotate around it's center, if the image is centered.
cairo_translate(cr, width / 2.0, height / 2.0);
cairo_rotate(cr, rotation_amt);
cairo_translate(cr, - image_w / 2.0, - image_h / 2.0);
cairo_set_source_surface(cr, image, 0, 0);
cairo_paint(cr);
I hope that's right.
And as ptomato said, you need to invalidate your drawing surface by calling gtk_widget_queue_draw from rotate_cb. And keeping a global variable for the Cairo context is redundant. The image doesn't rotate because a newly created context is loaded with an identity matrix and all your previous transformations are reset.
Problem
I've got a simple application that is supposed to rotate a decorated wheel so many degrees every x number of milliseconds using `GTK+` and `Cairo`. I've got some code below that calls `cairo_rotate()` from a timer. However, the image doesn't change. Do I have to invalidate the image to cause the expose-event to fire? I'm so new to Cairo that a simple example demonstrating how to rotate an image using `Cairo` in `GTK+` would be highly appreciated. ``` #include <cairo.h> #include <gtk/gtk.h> cairo_surface_t *image; cairo_t *cr; gboolean rotate_cb( void ) { cairo_rotate (cr, 1); //cairo_paint(cr); printf("rotating\n"); return( TRUE ); } static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) { cr = gdk_cairo_create (widget->window); cairo_set_source_surface(cr, image, 0, 0); cairo_paint(cr); printf("Paint\n"); //cairo_destroy(cr); return FALSE; } int main(int argc, char *argv[]) { GtkWidget *window; image = cairo_image_surface_create_from_png("wheel.png"); 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), 500, 500); gtk_widget_set_app_paintable(window, TRUE); gtk_widget_show_all(window); g_timeout_add(500, (GSourceFunc) rotate_cb, NULL); gtk_main(); cairo_destroy(cr); cairo_surface_destroy(image); return 0; } ```