This page contains samples of cairo's rendered output and the code snippets used to create them. The snippets are meant to be short, and easy to understand.
The original snippets were created by Øyvind Kolås for a paper submitted to GUADEC 2004. All of his original snippet code is considered to be part of the public domain.
arc
double xc = 128.0;
double yc = 128.0;
double radius = 100.0;
double angle1 = 45.0 * (M_PI/180.0); /* angles are specified */
double angle2 = 180.0 * (M_PI/180.0); /* in radians */
cairo_set_line_width (cr, 10.0);
cairo_arc (cr, xc, yc, radius, angle1, angle2);
cairo_stroke (cr);
/* draw helping lines */
cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
cairo_set_line_width (cr, 6.0);
cairo_arc (cr, xc, yc, 10.0, 0, 2*M_PI);
cairo_fill (cr);
cairo_arc (cr, xc, yc, radius, angle1, angle1);
cairo_line_to (cr, xc, yc);
cairo_arc (cr, xc, yc, radius, angle2, angle2);
cairo_line_to (cr, xc, yc);
cairo_stroke (cr);
arc negative

double xc = 128.0;
double yc = 128.0;
double radius = 100.0;
double angle1 = 45.0 * (M_PI/180.0); /* angles are specified */
double angle2 = 180.0 * (M_PI/180.0); /* in radians */
cairo_set_line_width (cr, 10.0);
cairo_arc_negative (cr, xc, yc, radius, angle1, angle2);
cairo_stroke (cr);
/* draw helping lines */
cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
cairo_set_line_width (cr, 6.0);
cairo_arc (cr, xc, yc, 10.0, 0, 2*M_PI);
cairo_fill (cr);
cairo_arc (cr, xc, yc, radius, angle1, angle1);
cairo_line_to (cr, xc, yc);
cairo_arc (cr, xc, yc, radius, angle2, angle2);
cairo_line_to (cr, xc, yc);
cairo_stroke (cr);
clip

cairo_arc (cr, 128.0, 128.0, 76.8, 0, 2 * M_PI);
cairo_clip (cr);
cairo_new_path (cr); /* current path is not
consumed by cairo_clip() */
cairo_rectangle (cr, 0, 0, 256, 256);
cairo_fill (cr);
cairo_set_source_rgb (cr, 0, 1, 0);
cairo_move_to (cr, 0, 0);
cairo_line_to (cr, 256, 256);
cairo_move_to (cr, 256, 0);
cairo_line_to (cr, 0, 256);
cairo_set_line_width (cr, 10.0);
cairo_stroke (cr);
clip image

int w, h;
cairo_surface_t *image;
cairo_arc (cr, 128.0, 128.0, 76.8, 0, 2*M_PI);
cairo_clip (cr);
cairo_new_path (cr); /* path not consumed by clip()*/
image = cairo_image_surface_create_from_png ("data/romedalen.png");
w = cairo_image_surface_get_width (image);
h = cairo_image_surface_get_height (image);
cairo_scale (cr, 256.0/w, 256.0/h);
cairo_set_source_surface (cr, image, 0, 0);
cairo_paint (cr);
cairo_surface_destroy (image);
curve rectangle
Unless you know what you are doing, you should probably use rounded rectangle instead.

/* a custom shape that could be wrapped in a function */
double x0 = 25.6, /* parameters like cairo_rectangle */
y0 = 25.6,
rect_width = 204.8,
rect_height = 204.8,
radius = 102.4; /* and an approximate curvature radius */
double x1,y1;
x1=x0+rect_width;
y1=y0+rect_height;
if (!rect_width || !rect_height)
return;
if (rect_width/2<radius) {
if (rect_height/2<radius) {
cairo_move_to (cr, x0, (y0 + y1)/2);
cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
} else {
cairo_move_to (cr, x0, y0 + radius);
cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
cairo_line_to (cr, x1 , y1 - radius);
cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
cairo_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
}
} else {
if (rect_height/2<radius) {
cairo_move_to (cr, x0, (y0 + y1)/2);
cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
cairo_line_to (cr, x1 - radius, y0);
cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
cairo_line_to (cr, x0 + radius, y1);
cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
} else {
cairo_move_to (cr, x0, y0 + radius);
cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
cairo_line_to (cr, x1 - radius, y0);
cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
cairo_line_to (cr, x1 , y1 - radius);
cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
cairo_line_to (cr, x0 + radius, y1);
cairo_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
}
}
cairo_close_path (cr);
cairo_set_source_rgb (cr, 0.5, 0.5, 1);
cairo_fill_preserve (cr);
cairo_set_source_rgba (cr, 0.5, 0, 0, 0.5);
cairo_set_line_width (cr, 10.0);
cairo_stroke (cr);
curve to

double x=25.6, y=128.0;
double x1=102.4, y1=230.4,
x2=153.6, y2=25.6,
x3=230.4, y3=128.0;
cairo_move_to (cr, x, y);
cairo_curve_to (cr, x1, y1, x2, y2, x3, y3);
cairo_set_line_width (cr, 10.0);
cairo_stroke (cr);
cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
cairo_set_line_width (cr, 6.0);
cairo_move_to (cr,x,y); cairo_line_to (cr,x1,y1);
cairo_move_to (cr,x2,y2); cairo_line_to (cr,x3,y3);
cairo_stroke (cr);
dash

double dashes[] = {50.0, /* ink */
10.0, /* skip */
10.0, /* ink */
10.0 /* skip*/
};
int ndash = sizeof (dashes)/sizeof(dashes[0]);
double offset = -50.0;
cairo_set_dash (cr, dashes, ndash, offset);
cairo_set_line_width (cr, 10.0);
cairo_move_to (cr, 128.0, 25.6);
cairo_line_to (cr, 230.4, 230.4);
cairo_rel_line_to (cr, -102.4, 0.0);
cairo_curve_to (cr, 51.2, 230.4, 51.2, 128.0, 128.0, 128.0);
cairo_stroke (cr);
dotnet-gdi-rendering
Using GDI+ Bitmap as surface can be as simple as that (given in managed C++):
// Create the target bitmap to draw to.
Drawing::Bitmap contentBitmap= new Drawing::Bitmap(Width, Height);
// Create a Graphics object to have a device context we can pass to cairo.
Graphics^ g = Graphics::FromImage(contentBitmap);
g->SmoothingMode = SmoothingMode::HighQuality;
// Do some drawing in GDI+ to have some initial content, like:
// Fill interior.
Brush^ brush = gcnew SolidBrush(Color::FromArgb(191, 1, 0, 0));
g->FillPath(brush, innerPath);
delete brush;
// Get the device context handle from this graphics object and create a Win32 cairo surface from it.
IntPtr hdc= g->GetHdc();
cairo_surface_t* surface= cairo_win32_surface_create((HDC) hdc.ToPointer());
// For drawing we need a cairo context.
cairo_t* cr= cairo_create(surface);
// Now you are ready to draw to that using any of the cairo calls.
...
// Don't forget the cleanup.
cairo_destroy(cr);
cairo_surface_destroy(surface);
g->ReleaseHdc(hdc);
This works quite well but has one big disadvantage: cairo_ win32_surface_create always returns a 24bit surface. So what if we have a bitmap with an alpha channel (like a png image we loaded and want to add something to it)? With the code above the alpha channel used in your cairo commands is lost.
One could create a 32bit DIB surface (using cairo_win32_surface_create_with_dib), but that creates a separate surface, which needs to be merged later to your actual target. Using an API like AlphaBlend (via pinvoke) produces exactly the same result as in the code above. So this is no help either.
The solution for this dilemma is an image surface (e.g. you get an image surface when you load png images in cairo).
// Instead of getting an HDC and and use cairo_win32_surface we get directly
// to the pixels in the bitmap and create the image surface from that.
Imaging::BitmapData^ bitmapData= contentBitmap->LockBits(Drawing::Rectangle(0, 0, Width, Height),
Imaging::ImageLockMode::ReadWrite, contentBitmap->PixelFormat);
unsigned char* data= (unsigned char*) bitmapData->Scan0.ToPointer();
cairo_surface_t* surface= cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, Width, Height,
bitmapData->Stride);
// The rest is the same as above, except we have to unlock the bits after we finished drawing.
contentBitmap->UnlockBits(bitmapData);
fill and stroke2

cairo_move_to (cr, 128.0, 25.6);
cairo_line_to (cr, 230.4, 230.4);
cairo_rel_line_to (cr, -102.4, 0.0);
cairo_curve_to (cr, 51.2, 230.4, 51.2, 128.0, 128.0, 128.0);
cairo_close_path (cr);
cairo_move_to (cr, 64.0, 25.6);
cairo_rel_line_to (cr, 51.2, 51.2);
cairo_rel_line_to (cr, -51.2, 51.2);
cairo_rel_line_to (cr, -51.2, -51.2);
cairo_close_path (cr);
cairo_set_line_width (cr, 10.0);
cairo_set_source_rgb (cr, 0, 0, 1);
cairo_fill_preserve (cr);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_stroke (cr);
fill style

cairo_set_line_width (cr, 6);
cairo_rectangle (cr, 12, 12, 232, 70);
cairo_new_sub_path (cr); cairo_arc (cr, 64, 64, 40, 0, 2*M_PI);
cairo_new_sub_path (cr); cairo_arc_negative (cr, 192, 64, 40, 0, -2*M_PI);
cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
cairo_set_source_rgb (cr, 0, 0.7, 0); cairo_fill_preserve (cr);
cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr);
cairo_translate (cr, 0, 128);
cairo_rectangle (cr, 12, 12, 232, 70);
cairo_new_sub_path (cr); cairo_arc (cr, 64, 64, 40, 0, 2*M_PI);
cairo_new_sub_path (cr); cairo_arc_negative (cr, 192, 64, 40, 0, -2*M_PI);
cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
cairo_set_source_rgb (cr, 0, 0, 0.9); cairo_fill_preserve (cr);
cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr);
gradient

cairo_pattern_t *pat;
pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0);
cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 0, 1);
cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1);
cairo_rectangle (cr, 0, 0, 256, 256);
cairo_set_source (cr, pat);
cairo_fill (cr);
cairo_pattern_destroy (pat);
pat = cairo_pattern_create_radial (115.2, 102.4, 25.6,
102.4, 102.4, 128.0);
cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1);
cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 0, 1);
cairo_set_source (cr, pat);
cairo_arc (cr, 128.0, 128.0, 76.8, 0, 2 * M_PI);
cairo_fill (cr);
cairo_pattern_destroy (pat);
image

int w, h;
cairo_surface_t *image;
image = cairo_image_surface_create_from_png ("data/romedalen.png");
w = cairo_image_surface_get_width (image);
h = cairo_image_surface_get_height (image);
cairo_translate (cr, 128.0, 128.0);
cairo_rotate (cr, 45* M_PI/180);
cairo_scale (cr, 256.0/w, 256.0/h);
cairo_translate (cr, -0.5*w, -0.5*h);
cairo_set_source_surface (cr, image, 0, 0);
cairo_paint (cr);
cairo_surface_destroy (image);
imagepattern

int w, h;
cairo_surface_t *image;
cairo_pattern_t *pattern;
cairo_matrix_t matrix;
image = cairo_image_surface_create_from_png ("data/romedalen.png");
w = cairo_image_surface_get_width (image);
h = cairo_image_surface_get_height (image);
pattern = cairo_pattern_create_for_surface (image);
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
cairo_translate (cr, 128.0, 128.0);
cairo_rotate (cr, M_PI / 4);
cairo_scale (cr, 1 / sqrt (2), 1 / sqrt (2));
cairo_translate (cr, -128.0, -128.0);
cairo_matrix_init_scale (&matrix, w/256.0 * 5.0, h/256.0 * 5.0);
cairo_pattern_set_matrix (pattern, &matrix);
cairo_set_source (cr, pattern);
cairo_rectangle (cr, 0, 0, 256.0, 256.0);
cairo_fill (cr);
cairo_pattern_destroy (pattern);
cairo_surface_destroy (image);
multi segment caps

cairo_move_to (cr, 50.0, 75.0);
cairo_line_to (cr, 200.0, 75.0);
cairo_move_to (cr, 50.0, 125.0);
cairo_line_to (cr, 200.0, 125.0);
cairo_move_to (cr, 50.0, 175.0);
cairo_line_to (cr, 200.0, 175.0);
cairo_set_line_width (cr, 30.0);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
cairo_stroke (cr);
rounded rectangle

/* a custom shape that could be wrapped in a function */
double x = 25.6, /* parameters like cairo_rectangle */
y = 25.6,
width = 204.8,
height = 204.8,
aspect = 1.0, /* aspect ratio */
corner_radius = height / 10.0; /* and corner curvature radius */
double radius = corner_radius / aspect;
double degrees = M_PI / 180.0;
cairo_new_sub_path (cr);
cairo_arc (cr, x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees);
cairo_arc (cr, x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees);
cairo_arc (cr, x + radius, y + height - radius, radius, 90 * degrees, 180 * degrees);
cairo_arc (cr, x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
cairo_close_path (cr);
cairo_set_source_rgb (cr, 0.5, 0.5, 1);
cairo_fill_preserve (cr);
cairo_set_source_rgba (cr, 0.5, 0, 0, 0.5);
cairo_set_line_width (cr, 10.0);
cairo_stroke (cr);
set line cap

cairo_set_line_width (cr, 30.0);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); /* default */
cairo_move_to (cr, 64.0, 50.0); cairo_line_to (cr, 64.0, 200.0);
cairo_stroke (cr);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
cairo_move_to (cr, 128.0, 50.0); cairo_line_to (cr, 128.0, 200.0);
cairo_stroke (cr);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
cairo_move_to (cr, 192.0, 50.0); cairo_line_to (cr, 192.0, 200.0);
cairo_stroke (cr);
/* draw helping lines */
cairo_set_source_rgb (cr, 1, 0.2, 0.2);
cairo_set_line_width (cr, 2.56);
cairo_move_to (cr, 64.0, 50.0); cairo_line_to (cr, 64.0, 200.0);
cairo_move_to (cr, 128.0, 50.0); cairo_line_to (cr, 128.0, 200.0);
cairo_move_to (cr, 192.0, 50.0); cairo_line_to (cr, 192.0, 200.0);
cairo_stroke (cr);
set line join

cairo_set_line_width (cr, 40.96);
cairo_move_to (cr, 76.8, 84.48);
cairo_rel_line_to (cr, 51.2, -51.2);
cairo_rel_line_to (cr, 51.2, 51.2);
cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER); /* default */
cairo_stroke (cr);
cairo_move_to (cr, 76.8, 161.28);
cairo_rel_line_to (cr, 51.2, -51.2);
cairo_rel_line_to (cr, 51.2, 51.2);
cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
cairo_stroke (cr);
cairo_move_to (cr, 76.8, 238.08);
cairo_rel_line_to (cr, 51.2, -51.2);
cairo_rel_line_to (cr, 51.2, 51.2);
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
cairo_stroke (cr);
text

cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cr, 90.0);
cairo_move_to (cr, 10.0, 135.0);
cairo_show_text (cr, "Hello");
cairo_move_to (cr, 70.0, 165.0);
cairo_text_path (cr, "void");
cairo_set_source_rgb (cr, 0.5, 0.5, 1);
cairo_fill_preserve (cr);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_set_line_width (cr, 2.56);
cairo_stroke (cr);
/* draw helping lines */
cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
cairo_arc (cr, 10.0, 135.0, 5.12, 0, 2*M_PI);
cairo_close_path (cr);
cairo_arc (cr, 70.0, 165.0, 5.12, 0, 2*M_PI);
cairo_fill (cr);
text align center

cairo_text_extents_t extents;
const char *utf8 = "cairo";
double x,y;
cairo_select_font_face (cr, "Sans",
CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (cr, 52.0);
cairo_text_extents (cr, utf8, &extents);
x = 128.0-(extents.width/2 + extents.x_bearing);
y = 128.0-(extents.height/2 + extents.y_bearing);
cairo_move_to (cr, x, y);
cairo_show_text (cr, utf8);
/* draw helping lines */
cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
cairo_set_line_width (cr, 6.0);
cairo_arc (cr, x, y, 10.0, 0, 2*M_PI);
cairo_fill (cr);
cairo_move_to (cr, 128.0, 0);
cairo_rel_line_to (cr, 0, 256);
cairo_move_to (cr, 0, 128.0);
cairo_rel_line_to (cr, 256, 0);
cairo_stroke (cr);
text extents

cairo_text_extents_t extents;
const char *utf8 = "cairo";
double x,y;
cairo_select_font_face (cr, "Sans",
CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (cr, 100.0);
cairo_text_extents (cr, utf8, &extents);
x=25.0;
y=150.0;
cairo_move_to (cr, x,y);
cairo_show_text (cr, utf8);
/* draw helping lines */
cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
cairo_set_line_width (cr, 6.0);
cairo_arc (cr, x, y, 10.0, 0, 2*M_PI);
cairo_fill (cr);
cairo_move_to (cr, x,y);
cairo_rel_line_to (cr, 0, -extents.height);
cairo_rel_line_to (cr, extents.width, 0);
cairo_rel_line_to (cr, extents.x_bearing, -extents.y_bearing);
cairo_stroke (cr);
