#include #include #include #define WIDTH 640 #define HEIGHT 480 #define ZOOM_X 100.0 #define ZOOM_Y 100.0 gfloat f (gfloat x) { return 0.03 * pow (x, 3); } static gboolean on_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { cairo_t *cr = gdk_cairo_create (widget->window); GdkRectangle da; /* Dimensions de la GtkDrawingArea */ gdouble dx = 5.0, dy = 5.0; /* Nombre de pixels entre chaque point calculé */ gdouble i, clip_x1 = 0.0, clip_y1 = 0.0, clip_x2 = 0.0, clip_y2 = 0.0; gint unused = 0; /* On définit la zone de clipping, cela correspond à la zone à * raffraîchir. En ne dessinant que le strict nécessaire, on dessinera * plus rapidement */ cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height); cairo_clip (cr); /* On détermine les dimensions de la GtkDrawingArea */ gdk_window_get_geometry (widget->window, &da.x, &da.y, &da.width, &da.height, &unused); /* On dessine un fond noir */ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); cairo_paint (cr); /* On change la matrice de transformation. C'est comme un changement * de repère en mathématiques. On centre d'abord l'origine du repère. * Ensuite on change son échelle */ cairo_translate (cr, da.width / 2, da.height / 2); cairo_scale (cr, ZOOM_X, -ZOOM_Y); /* On détermine les points à calculer (c'est à dire ceux se trouvant * dans la zone de clipping) */ cairo_device_to_user_distance (cr, &dx, &dy); cairo_clip_extents (cr, &clip_x1, &clip_y1, &clip_x2, &clip_y2); cairo_set_line_width (cr, dx); /* On dessine les axes */ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); cairo_move_to (cr, clip_x1, 0.0); cairo_line_to (cr, clip_x2, 0.0); cairo_move_to (cr, 0.0, clip_y1); cairo_line_to (cr, 0.0, clip_y2); cairo_stroke (cr); /* On rajoute les points de la coube en les reliants par une droite */ for (i = clip_x1; i < clip_x2; i += dx) cairo_line_to (cr, i, f (i)); /* On dessine la courbe */ cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6); cairo_stroke (cr); cairo_destroy (cr); return FALSE; } int main (int argc, char **argv) { GtkWidget *window; GtkWidget *da; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW (window), WIDTH, HEIGHT); gtk_window_set_title (GTK_WINDOW (window), "Affichage de courbe"); g_signal_connect (G_OBJECT (window), "delete-event", gtk_main_quit, NULL); da = gtk_drawing_area_new (); gtk_container_add (GTK_CONTAINER (window), da); g_signal_connect (G_OBJECT (da), "expose-event", G_CALLBACK (on_expose_event), NULL); gtk_widget_show_all (window); gtk_main (); return 0; }