Cairo provides functions for doing rotations and scaling about the origin: `cairo_rotate()` and `cairo_scale()` for directly affecting the transformation matrix of a context, and `cairo_init_rotate()`/`cairo_rotate()` and `cairo_init_scale()`/`cairo_scale()` for computing a transformation matrix separately from a context. But what if you want to perform rotation or scaling about a point *other* than the origin?

In fact, this is quite simple. Break up the transformation into 3 separate steps:

- perform a translation that moves the specified point to the origin
- perform the desired rotation or scaling about the origin
- perform the inverse of the translation in step 1, moving the origin back to the specified point.

In Cairo code, these steps have to be performed in the reverse order (see here for why). Supposing we want to rotate by *angle* radians about the point (*centre_x*, *centre_y*). The code would look like

```
cairo_translate(cr, centre_x, centre_y); /* step 3 */
cairo_rotate(cr, angle); /* step 2 */
cairo_translate(cr, - centre_x, - centre_y); /* step 1 */
```

where the comments refer to the steps in the previous list.

Similarly, if we wanted to compute such a transformation as a separate matrix for use later, we could do it like

```
cairo_matrix_t mat;
cairo_matrix_init_identity(&mat);
cairo_matrix_translate(&mat, centre_x, centre_y); /* step 3 */
cairo_matrix_rotate(&mat, angle); /* step 2 */
cairo_matrix_translate(&mat, - centre_x, - centre_y); /* step 1 */
```

Here I could have used `cairo_matrix_init_translate()` to combine the first two Cairo calls into one, but I kept them separate so it is clear that the second call corresponds exactly to step 3 in the above list.