Basic drawing

Code: examples/cairo-rectangle.py on github

Cairo basics

There are two important objects we need to know bout when using Cairo - the surface and the context.

The surface represents the actual drawing you are creating. This might be an image file (such as a PNG file), a vector drawing file (such as RGB), or a graphic which appears in a window on your computer, etc. Each different type of drawing uses a different type of surface.

The context holds the actual instructions to draw your picture. If you want to draw a red rectangle and a blue circle, you call the context to tell it what to do.

Using a separate context means that we can use exactly the same drawing code whether we are creating a PNG file or drawing in a window. We use a different type of surface, but the context is the same.

The way Cairo works is as follows:

  • Create a surface
  • Request a context using the surface
  • Call drawing methods on the context
  • Finalise the surface (for example save it to file) to create the output

A simple drawing

Here is the complete code to create an image with a rectangle drawn on a transparent background:

import cairo
 
width = 500
height = 500
 
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
ctx = cairo.Context(surface)
 
ctx.rectangle (100, 150, 300, 200) # Rectangle(x0, y0, x1, y1)
ctx.set_source_rgb (0.8, 0.3, 0.3) # Solid color
ctx.fill ()
 
surface.write_to_png("cairo_rectangle.png") # Output to PNG

Let's look at the code step by step. First, we import the cairo module and declare our image width and height in pixels:

import cairo
 
width = 500
height = 500

Now we create our surface. The surface determines what type of drawing we are going to make. In this case, because we use the ImageSurface method we are choosing to create a PNG image. We will see later how to make an SVG vector image of the type used by Inkscape.

The FORMAT_ARGB32 parameter says that we want to create an image which uses RGB with transparency support (the A stands for alpha, and alpha channel stores transparency). The 32 means there are 8 bit per colour (RGB+A = four colours). This is fairly standard, you will probably use that for most images.

We also set the width and height of the image in pixels.

We get a drawing context (ctx) for the image.

surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
ctx = cairo.Context(surface)

Here is the actual drawing code. We use the rectangle function to create a rectangular path. A path is the name for any shape we create in Cairo, be it a rectangle, circle, polygon or anything else. A path can even be a collection of different shapes. Just creating a path doesn't actually draw anything.

Next we use set_source_rgb to set a source colour using the red, green and blue values given - in this case a muddy red. Again, nothing is actually drawn yet.

Then we call the fill function. This function takes the current path (a rectangle) and fills it with the current colour (red). This is the stage which actually draws something.

ctx.rectangle (100, 150, 300, 200) # Rectangle(x0, y0, x1, y1)
ctx.set_source_rgb (0.8, 0.3, 0.3) # Solid color
ctx.fill ()

The final step is to save the file as a png file.

surface.write_to_png("cairo_rectangle.png") # Output to PNG