Cairo 2D vector graphics. Draw to PNG, PDF, or SVG with paths, text, transforms, gradients, and clipping.
ppm install cairo
Requires libcairo2-dev: sudo apt install libcairo2-dev
Overview
Cairo is the standard 2D vector graphics library on Linux, used by GTK, GNOME, Firefox, and Inkscape.
It renders to PNG images, PDF documents, and SVG files with identical output.
All drawing is anti-aliased and sub-pixel accurate.
Coordinate system: origin top-left, Y increases downward.
Quick Start — Draw to PNG
uses cairo;
var surface := NewImageSurface(800, 600);
var ctx := NewContext(surface);
{ Background }
SetSourceRGB(ctx, 0.05, 0.05, 0.1);
Paint(ctx);
{ Blue filled circle }
SetSourceRGBA(ctx, 0.2, 0.5, 1.0, 0.9);
Arc(ctx, 400, 300, 120, 0, 6.2832); { 2*pi }
Fill(ctx);
{ White text centered }
SelectFont(ctx, 'Sans', cairoFontSlantNormal, cairoFontWeightBold);
SetFontSize(ctx, 36);
SetSourceRGB(ctx, 1, 1, 1);
var ext := MeasureText(ctx, 'Hello Cairo!');
TextAt(ctx, 400 - ext.Width/2, 310, 'Hello Cairo!');
SurfaceWriteToPNG(surface, '/tmp/output.png');
DestroyContext(ctx);
DestroySurface(surface);
Gradients
{ Linear gradient: left (blue) to right (purple) }
var grad := NewLinearGradient(0, 0, 800, 0);
AddColorStop(grad, 0.0, 0.1, 0.3, 0.9, 1.0);
AddColorStop(grad, 1.0, 0.6, 0.1, 0.9, 1.0);
SetSource(ctx, grad);
Rectangle(ctx, 0, 0, 800, 100);
Fill(ctx);
DestroyPattern(grad);
{ Radial gradient: glowing dot }
var radial := NewRadialGradient(400, 300, 0, 400, 300, 150);
AddColorStop(radial, 0.0, 1.0, 1.0, 0.8, 1.0);
AddColorStop(radial, 1.0, 0.0, 0.0, 0.0, 0.0);
SetSource(ctx, radial);
Arc(ctx, 400, 300, 150, 0, 6.2832);
Fill(ctx);
DestroyPattern(radial);
Transforms & Clipping
Save(ctx);
{ Rotate 45 degrees around center }
Translate(ctx, 400, 300);
Rotate(ctx, 0.7854); { pi/4 }
Translate(ctx, -400, -300);
SetSourceRGB(ctx, 1, 0.5, 0);
Rectangle(ctx, 300, 200, 200, 200);
Fill(ctx);
Restore(ctx); { transform is gone, back to normal }
{ Clip to a circle }
Arc(ctx, 400, 300, 100, 0, 6.2832);
Clip(ctx);
{ All subsequent drawing is clipped to the circle }
SetSourceRGB(ctx, 0, 0.8, 0.4);
Paint(ctx);
ResetClip(ctx);
PDF & SVG Output
{ Generate a PDF }
var pdf := NewPDFSurface('/tmp/report.pdf', 595, 842); { A4 }
var c := NewContext(pdf);
SelectFont(c, 'Serif', cairoFontSlantNormal, cairoFontWeightBold);
SetFontSize(c, 18);
TextAt(c, 72, 72, 'Page 1');
ShowPage(c); { advance to page 2 }
TextAt(c, 72, 72, 'Page 2');
SurfaceFinish(pdf);
DestroyContext(c);
DestroySurface(pdf);
{ Generate SVG }
var svg := NewSVGSurface('/tmp/chart.svg', 400, 300);
{ ... draw ... }
SurfaceFinish(svg);
API Reference
Surfaces
| Function | Description |
| NewImageSurface(W, H) | Create in-memory ARGB pixel surface. |
| NewPDFSurface(Path, W, H) | Create PDF output (multi-page). |
| NewSVGSurface(Path, W, H) | Create SVG output. |
| LoadPNG(Path) | Load PNG file as surface (for image compositing). |
| SurfaceWriteToPNG(Surface, Path) | Save image surface to PNG file. |
| SurfaceToBytes(Surface) | Return PNG as byte string. |
| SurfaceFinish(Surface) | Flush and finalize multi-page surface. |
| ShowPage(Ctx) | Advance to next page (PDF). |
| DestroySurface(Surface) | Free surface. |
Context & State
| Function | Description |
| NewContext(Surface) | Create drawing context. |
| DestroyContext(Ctx) | Free context. |
| Save(Ctx) / Restore(Ctx) | Push/pop graphics state (color, transform, clip). |
Color & Patterns
| Function | Description |
| SetSourceRGB/RGBA(Ctx, R,G,B[,A]) | Solid color. Values 0.0–1.0. |
| SetSource(Ctx, Pattern) | Use a gradient or image pattern. |
| SetSourceSurface(Ctx, Surface, X, Y) | Use an image surface as source. |
| NewLinearGradient(X1,Y1,X2,Y2) | Linear gradient between two points. |
| NewRadialGradient(CX1,CY1,R1,CX2,CY2,R2) | Radial gradient. |
| AddColorStop(Pat, Offset, R,G,B,A) | Add a color stop at 0.0–1.0. |
| NewSurfacePattern(Surface) | Image pattern for tiling/stamping. |
| DestroyPattern(Pattern) | Free pattern. |
Paths & Paint
| Function | Description |
| MoveTo / LineTo(Ctx, X, Y) | Path construction. |
| RelMoveTo / RelLineTo(Ctx, DX, DY) | Relative path construction. |
| CurveTo(Ctx, X1,Y1,X2,Y2,X3,Y3) | Cubic Bezier curve. |
| Arc(Ctx, CX,CY,R,A1,A2) | Arc or full circle (angles in radians). |
| Rectangle(Ctx, X,Y,W,H) | Add rectangle to current path. |
| ClosePath(Ctx) | Close sub-path back to start. |
| Paint(Ctx) | Fill entire surface. |
| PaintWithAlpha(Ctx, Alpha) | Fill entire surface with alpha. |
| Stroke(Ctx) / StrokePreserve(Ctx) | Stroke current path. |
| Fill(Ctx) / FillPreserve(Ctx) | Fill current path. |
| Clip(Ctx) / ResetClip(Ctx) | Clip to path / reset clip. |
Text & Transforms
| Function | Description |
| SelectFont(Ctx, Family, Slant, Weight) | Choose font face. |
| SetFontSize(Ctx, Size) | Set font size in user units. |
| TextAt(Ctx, X, Y, Text) | Draw text at position. |
| ShowText(Ctx, Text) | Draw text at current point. |
| MeasureText(Ctx, Text) | Returns TCairoTextExtents (width, height, advance). |
| Translate/Scale/Rotate(Ctx, ...) | Affine transforms. |
| IdentityMatrix(Ctx) | Reset transform to identity. |
| SetLineWidth/Cap/Join/Dash(Ctx, ...) | Stroke style. |