Cairo 2D Graphics — Core Concepts
What Cairo is
Cairo is a C library for 2D vector graphics with bindings for many languages. In Python, the pycairo package provides access. Cairo was originally created for the GNOME project and has been battle-tested since 2003 in desktop environments, PDF generators, and mapping tools. It draws anti-aliased, resolution-independent graphics using a PostScript-inspired drawing model.
The surface and context model
Cairo separates what you draw on (the surface) from how you draw (the context).
Surfaces represent output targets:
ImageSurface— raster pixels (PNG output)PDFSurface— vector PDF filesSVGSurface— scalable vector graphicsPSSurface— PostScript files
Context is the drawing tool. You create a context attached to a surface, then issue drawing commands: move to a point, draw a line, create an arc, fill a shape, stroke an outline. The context tracks the current path, line width, color, font, and transformation matrix.
This separation is powerful. You can write a function that draws a dashboard, then call it with an ImageSurface for web previews and a PDFSurface for print — same drawing code, different output.
Drawing model
Cairo follows a path-based drawing model with three phases:
1. Path construction
Build a path by combining moves, lines, curves, and arcs. Paths are invisible until you fill or stroke them.
2. Filling and stroking
- Fill paints the interior of a closed path with the current source color or pattern.
- Stroke paints the outline of the path using the current line width and style.
3. Source patterns
The “paint” used for fill and stroke can be a solid color, a linear gradient, a radial gradient, or even another surface (for tiling patterns or image compositing).
Coordinate system and transformations
Cairo uses a Cartesian coordinate system with the origin at the top-left corner by default. You can apply affine transformations — translate, rotate, scale — to the context’s transformation matrix. These apply to all subsequent drawing operations until reset.
This makes it easy to draw repeated elements at different positions and angles without recalculating coordinates manually. For example, drawing a clock face involves rotating the context by 30 degrees twelve times and drawing a tick mark at the same position each time.
Text rendering
Cairo handles text through two APIs:
- Toy text API — Simple text rendering with
select_font_face()andshow_text(). Good for labels and annotations. - FreeType/Fontconfig integration — For production typography with proper glyph shaping, use Pango (a text-layout library) with PangoCairo. This handles complex scripts, bidirectional text, and font fallback.
Common misconception
People sometimes confuse Cairo with Pillow (PIL). Pillow is a raster image manipulation library — it loads, filters, and saves bitmap images. Cairo is a vector drawing library — it constructs paths and renders them at any resolution. They solve different problems, though both can produce PNG files.
Where Cairo fits
- Desktop UI toolkits — GTK uses Cairo for widget rendering.
- PDF/report generation — Programmatic document creation with precise layout control.
- Map rendering — Mapnik (the OpenStreetMap renderer) uses Cairo as a backend.
- Scientific figures — When Matplotlib’s output is not customizable enough, Cairo offers lower-level control.
- Game/app UI — Custom-drawn interfaces without relying on widget toolkits.
One thing to remember
Cairo’s surface-context split means you write drawing logic once and output to any format — PNG, PDF, SVG — making it the Swiss Army knife of 2D graphics in Python.
See Also
- Python Adaptive Learning Systems How Python builds learning apps that adjust to each student like a personal tutor who knows exactly what you need next.
- Python Airflow Learn Airflow as a timetable manager that makes sure data tasks run in the right order every day.
- Python Altair Learn Altair through the idea of drawing charts by describing rules, not by hand-placing every visual element.
- Python Automated Grading How Python grades homework and exams automatically, from simple answer keys to understanding written essays.
- Python Batch Vs Stream Processing Batch processing is like doing laundry once a week; stream processing is like a self-cleaning shirt that cleans itself constantly.