GtkDrawingArea and Cairo

If you want to draw dynamically on the screen, like an image window of gimp graphics editor, the GtkDrawingArea widget is the most suitable widget. You can freely draw or redraw an image in this widget. This is called custom drawing.

GtkDrawingArea provides a cairo drawing context so users can draw images by using cairo functions. In this section, I will explain:

  1. Cairo, but only briefly
  2. GtkDrawingArea, with a very simple example.

Cairo

Cairo is a set of two dimensional graphical drawing functions (or graphics library). There are a lot of documents on Cairo’s website. If you aren’t familiar with Cairo, it is worth reading the tutorial.

The following is an introduction to the Cairo library and how to use it. First, you need to know about surfaces, sources, masks, destinations, cairo context and transformations.

Stroke a rectangle

The instruction is as follows:

  1. Create a surface. This will be the destination.
  2. Create a cairo context with the surface, the surface will be the destination of the context.
  3. Create a source pattern within the context.
  4. Create paths, which are lines, rectangles, arcs, texts or more complicated shapes in the mask.
  5. Use a drawing operator such as cairo_stroke to transfer the paint in the source to the destination.
  6. Save the destination surface to a file if necessary.

Here’s a simple example program that draws a small square and saves it as a png file. The path of the file is src/misc/cairo.c.

@@@include misc/cairo.c @@@

To compile this, change your current directory to src/misc and type the following.

$ gcc `pkg-config --cflags cairo` cairo.c `pkg-config --libs cairo`
rectangle.png

See the Cairo’s website for further information.

GtkDrawingArea

The following is a very simple example.

@@@include misc/da1.c @@@

The function main is almost same as before. The two functions app_activate and draw_function are important in this example.

The drawing function has five parameters.

void drawing_function (GtkDrawingArea *drawing_area, cairo_t *cr, int width, int height,
                       gpointer user_data);

The first parameter is the GtkDrawingArea widget. You can’t change any properties, for example content-width or content-height, in this function. The second parameter is a cairo context given by the widget. The destination surface of the context is connected to the contents of the widget. What you draw to this surface will appear in the widget on the screen. The third and fourth parameters are the size of the destination surface. Now, look at the program again.

The program is src/misc/da1.c. Compile and run it, then a window with a black rectangle (square) appears. Try resizing the window. The square always appears at the center of the window because the drawing function is invoked each time the window is resized.

Square in the window