Cairo (graphics)
Cairo (stylized as cairo) is an open-source graphics library that provides a vector graphics-based, device-independent API for software developers. It provides primitives for two-dimensional drawing across a number of different back ends. Cairo uses hardware acceleration[4] when available.
![]() ![]() | |
Original author(s) | Keith Packard, Carl Worth[1] |
---|---|
Developer(s) | Carl Worth, Behdad Esfahbod |
Initial release | Before 2003[2] |
Stable release | 1.16.0 (October 19, 2018[3]) [±] |
Repository | gitlab |
Written in | C |
Type | Graphics library |
License | GNU Lesser General Public License version 2.1 (only) or Mozilla Public License 1.1 |
Website | www |
Software architecture
Language bindings
A library written in one programming language may be used in another language if bindings are written; Cairo has a range of bindings for various languages including C++, C# and other CLI languages, Delphi, Eiffel, Factor, Harbour, Haskell, Julia, Lua, Perl, PHP, Python, Ruby, Rust, Scheme, Smalltalk and several others like Gambas (Visual Basic like).[5]
Toolkit bindings
Since Cairo is only a drawing library, it can be quite useful to integrate it with a graphical user interface toolkit.
- FLTK has full Cairo support (through
--enable-cairo
compile switch). - GTK began in 2005, with version 2.8, to use Cairo to render the majority of its graphical control elements, and since version 3.0 all rendering is done through Cairo.
- The Cairo development team maintains up-to-date instructions for rendering surfaces to SDL.[6]
Available back-ends
Cairo supports output (including rasterisation) to a number of different back-ends, known as "surfaces" in its code. Back-ends support includes output to the X Window System, via both Xlib and XCB, Win32 GDI, OS X Quartz Compositor, the BeOS API, OS/2, OpenGL contexts (directly[7] and via glitz), local image buffers, PNG files, PDF, PostScript, DirectFB and SVG files.
There are other back-ends in development targeting the graphics APIs OpenVG,[8] Qt,[9] Skia,[10] and Microsoft's Direct2D.[11] The BeOS, OS/2 and DirectFB backends were dropped in 2022.[12]
Drawing model

The Cairo drawing model relies on a three-layer model.
Any drawing process takes place in three steps:
- First a mask is created, which includes one or more vector primitives or forms, i.e., circles, squares, TrueType fonts, Bézier curves, etc.
- Then source must be defined, which may be a color, a color gradient, a bitmap or some vector graphics, and from the painted parts of this source a die cut is made with the help of the above defined mask.
- Finally the result is transferred to the destination or surface, which is provided by the back-end for the output.
This constitutes a fundamentally different approach from Scalable Vector Graphics (SVG), which specifies the color of shapes with Cascading Style Sheets (CSS) rules. Whereas Cairo would create a mask of a shape, then make a source for it, and then transfer them onto the surface, an SVG file would simply specify the shape with a style
attribute. That said, the models are not incompatible; many SVG renderers use Cairo for heavy lifting.[13]
Example

Quite complex "Hello world" graphics can be drawn with the help of Cairo with only a few lines of source code:
#include <cairo-svg.h>
#include <stdio.h>
int main(int argc, char **argv) {
cairo_surface_t *surface = cairo_svg_surface_create("Cairo_example.svg", 100.0, 100.0);
cairo_t *cr = cairo_create(surface);
/* Draw the squares in the background */
for (int x = 0; x < 10; ++x)
for (int y = 0; y < 10; ++y)
cairo_rectangle(cr, x * 10.0, y * 10.0, 5, 5);
cairo_pattern_t *pattern = cairo_pattern_create_radial(50, 50, 5, 50, 50, 50);
cairo_pattern_add_color_stop_rgb(pattern, 0, 0.75, 0.15, 0.99);
cairo_pattern_add_color_stop_rgb(pattern, 0.9, 1, 1, 1);
cairo_set_source(cr, pattern);
cairo_fill(cr);
/* Writing in the foreground */
cairo_set_font_size (cr, 15);
cairo_select_font_face (cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_move_to(cr, 10, 25);
cairo_show_text(cr, "Hallo");
cairo_move_to(cr, 10, 75);
cairo_show_text(cr, "Wikipedia!");
cairo_destroy(cr);
cairo_surface_destroy(surface);
}
Notable usage
Cairo is popular in the open source community for providing cross-platform support for advanced 2D drawing.
- GTK, starting in 2005 with version 2.8, uses Cairo to render the majority of its graphical control elements.[14] Since GTK version 3, all the rendering is done using Cairo.
- A program called gtk-vector-screenshot found in Debian allows for taking vector (SVG, PDF, or PostScript) screenshots of GTK 3 applications.[15]
- The Mono Project,[16] including Moonlight,[17] has been using Cairo since very early in conception to power the back-ends of its GDI+ (libgdiplus) and System.Drawing namespaces.
- The Mozilla project has made use of Cairo in its Gecko layout engine, used for rendering the graphical output of Mozilla products. Gecko 1.8, the layout engine for Mozilla Firefox 2.0 and SeaMonkey 1.0, used Cairo to render SVG and <canvas> content. Gecko 1.9,[18] the release of Gecko that serves as the basis of Firefox 3, uses Cairo as the graphics back-end for rendering both web page content and the user interface (or "chrome").
- The WebKit framework uses Cairo for all rendering in the GTK and EFL ports. Support has also been added for SVG and <canvas> content using Cairo.
- The Poppler library uses Cairo to render PDF documents. Cairo enables the drawing of antialiased vector graphics and transparent objects.
- The vector graphics application Inkscape uses the Cairo library for its outline mode display, as well as for PDF and PostScript export since release 0.46.[19]
- The original version of Manim referred to as ManimCairo, a mathematical animation engine used in the animations of 3Blue1Brown's YouTube Videos. Manim has since moved to using OpenGL. This version is referred to as ManimGL.[20]
- MorphOS 2.5 features a shared library implementation of Cairo, which was available as stand-alone release for earlier MorphOS versions.
- AmigaOS 4.1 supports a shared object library of Cairo (libcairo.so) in its default installation.
- FontForge enabled Cairo by default for rendering in mid-October 2008.
- R can output plots in PDF, PostScript and SVG formats using Cairo if available.
- Gnuplot 4.4 now uses Cairo for rendering PDF and PNG output.[21]
- Internet Browser for PlayStation 3 uses Cairo since system software update 4.10.
- Synfig 0.64 now supports optional Cairo rendering.
- On-demand graphing of time series data in Graphite.
- The Konfabulator/Yahoo widget engine uses Cairo for identical output to both Win32 and Quartz on Mac OS/X.
- SolveSpace, free and open source 2D and 3D CAD software.
Context
Rendering text and graphics onto computer screens has been done for a while, but how it is done has changed as screens got more and more pixels. Rendering text characters used to be done by copying bitmaps from a font-file that contained a bitmap for all characters of language(s) it supported. When a little more pixels became available, "anti-aliasing" was added, which is the use of greyscale pixels to make slanted lines look less jagged.
As screens got more pixels, better looking characters could be drawn, using an outline specified as a series of curves and straigh lines that can be converted to a series of short line-segments ("vectors"). This made it possible to scale the outline to get a bigger font, hence these are called "scalable" fonts.
These days, both types of fonts are still around, and there is software to handle them. On linux, most notably :
- fontconfig, which keeps track of all fontfiles, and can detect which fonts are in them
- freetype, which can read all fontfile formats and render fonts onto screen (as grayscale pixelmaps)
- cairo, which can use freetype to get vector-description of a font's characters and rotate them as vectors, and then render them to pixels, which looks much better than trying to rotate rendered pixelmaps.
- pango, which can combine all kinds of accents with character shapes
Cairo can also draw all kinds of lines and shapes, and fill them with solid or gradient colors.
Application Program Interface
Cairo has two programming interfaces, a simple.ish one which it's developers call "toy interface", which can do nearly everything that doesn't require acces to underlying vector-description of glyphs, but is limited in which fontfiles can be selected (only "bold" and "italic" are supported, not "demibold" or "black" or "oblique"). And there is an interface for more advanced use, for which the user really needs to know libfreetype. Both are described in some detail in cairo documentation (see below).
How to use it
// compile with :
// cc cairo.howto.c -I/usr/include/cairo -I/usr/include/freetype2 -lcairo -lm -o cairohowto
#include <stdio.h>
#include <math.h>
#include <cairo.h>
#include <cairo-xlib.h> // to use cairo to draw to an X.org surface, also include this
int main( void ){
cairo_t * pR ; // main struct (cf GC with send/receive.buffer)
cairo_status_t Rerrno ; // integer status. 0=ok
cairo_surface_t * pRos ; // cairo output surface
// step 1 : create an output surface (a "paper" to draw on), for output medium you use
// by calling a function name "cairo_???_surface_create, where ??? is name of that medium.
// if you draw on X, make sure to get default visual from a call to an XDefaultVisual.. macro
// not from a locally copied visual ; presumably cairo accesses render extension through it.
// it is always possible to draw to an image buffer, with cairo_image_surface_create(),
// as will be done in this example :
pRos = cairo_image_surface_create( CAIRO_FORMAT_RGB24, 500 /*width*/, 500 /*height*/ );
// step 2 : get a cairo drawing context (cf x's GC) for that surface :
// (it contains many default values, such as line-width)
pR = cairo_create( pRos );
// step 3 : specify an ink/color source, simplest is a solid color (red in this case) :
cairo_set_source_rgb( pR, 1.0, 0.0, 0.0 );
// step 4 : draw a shape (simplest is a rectangle) :
cairo_rectangle( pR, /*x*/ 300.0, /*y*/ 300.0, /*wi*/ 100.0, /*hi*/ 100.0 );
// step 5 : fill it, so it gets drawn on output medium :
cairo_fill( pR );
// YEE ! , your first cairo drawing
// step 6 : you'll want a picture of that ! :
cairo_surface_t * pRis ; // image surface
pRis = cairo_surface_map_to_image( pRos, NULL );
// you can get a sub-image by specifying a limiting rectangle,
// but for now just specify NULL, to get image of whole output surface.
Rerrno = cairo_surface_status( pRis );
if( Rerrno != CAIRO_STATUS_SUCCESS ){ printf("error getting image\n"); return(0); }
// success of many functions can be tested with statements such as these
Rerrno = cairo_surface_write_to_png( pRis, "cairo.image.png" );
if( Rerrno != CAIRO_STATUS_SUCCESS ){ printf("error for write png\n"); return(0); }
// resulting image file should now be present on your system,
// and you can view it with any image-viewer program.
// step 7 : going a little bit further : rotating :
double x, y ;
cairo_move_to( pR, 100, 100 );
cairo_rotate( pR, M_PI / 8.0 );
// sets rotation in matrix, to affect all following vectors
cairo_set_source_rgb( pR, 0.0, 1.0, 0.0 );
cairo_rectangle( pR, 100, 100, 30.0, 30.0 );
cairo_fill( pR );
cairo_identity_matrix( pR ); // undo rotation setting
cairo_set_source_rgb( pR, 0.0, 1.0, 1.0 );
cairo_move_to( pR, 150, 150 );
cairo_rotate( pR, M_PI / 8.0 );
cairo_rectangle( pR, 150, 150, 30.0, 30.0 );
cairo_rel_move_to( pR, 50, 0 );
cairo_get_current_point( pR, &x, &y );
cairo_rectangle( pR, x, y, 30.0, 30.0 );
cairo_set_source_rgb( pR, 0.0, 0.0, 1.0 );
cairo_fill( pR );
cairo_identity_matrix( pR ); // undo rotation setting
// as you see, setting source color does not take effect until cairo_fill() is called
// step 8 : now try drawing text :
// first load a font.
// to do that you need to know a name of a scalable font that is present on your system.
// On linux, look in /usr/share/fonts/truetype
// for example, on my system i have (among many others)
// /usr/share/fonts/truetype/ubuntu/UbuntuMono-B.ttf
// that is the name of the file .
// then in a terminal do : 'fc-list | grep Ubuntu'
// fc-list is a commandline program provided by fontconfig, it tells about installed fonts
// output from that is (among others) :
// /usr/share/fonts/truetype/ubuntu/UbuntuMono-B.ttf: Ubuntu Mono:style=Bold
// so the name of the font is "Ubuntu Mono", with a space.
// now make cairo load that font :
cairo_select_font_face( pR, "UbuntuMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD );
// so here one needs to use "UbuntuMono", without space, as in it's filename,
// otherwise cairo will not find this font.
// define how large this font's shapes should be drawn :
cairo_set_font_size( pR, 30.0 );
// draw a text :
cairo_move_to( pR, 150, 150 );
cairo_set_source_rgb( pR, 1.0, 1.0, 0.0 );
cairo_show_text( pR, "This is a text" );
pRis = cairo_surface_map_to_image( pRos, NULL );
Rerrno = cairo_surface_write_to_png( pRis, "cairo.image.png" );
return(0);
}
Documentation
Main documentation for libcairo is at https://www.cairographics.org/manual-1.12.4/index.html . There is a lot of info there, but a lot is also left unexplained. Much of that unexplained can be found out by trying, e.g. how to rotate around a point other than origin, but some major concepts are still missing, e.g. "FcPattern" and "device space".
Bugs
The model of creating a colored surface and using it to "shine-through" shapes that are drawn
works well with geometric shapes such as rectangles, but does not seem to work when drawing characters,
as is shown in the image below.
History
Keith Packard and Carl Worth founded the Cairo project for use in the X Window System.[2] It was originally (until at least 2003) called Xr or Xr/Xc. The name was changed to emphasize the idea of a cross-platform library to access display server, not tied to the X Window System.[22] The name Cairo derives from the original name Xr, interpreted as the Greek letters chi and rho.[23]
Complex text layout
Cairo handles Latin and CJK based fonts, but does not support complex text layout fonts, which require shaping the glyphs.[24]
See also
References
- "Carl's boring web pages". cworth.org. 2013. Retrieved 11 July 2014.
- "Xr: Cross-device Rendering for Vector Graphics". Retrieved 2009-06-08.
- "Latest cairo news". Retrieved 6 October 2022.
- "Cairo homepage". Retrieved 2010-10-30.
- "Cairo Language Bindings". Retrieved 2014-04-16.
- "SDL". Cairo. 2009-02-17. Retrieved 2014-11-03.
- Chris Wilson (2009-07-22). "New OpenGL backend merged". Retrieved 2010-02-12.
- Øyvind Kolås (2008-01-24). "Announcing OpenVG backend". Retrieved 2010-02-12.
- Vladimir Vukićević (2008-05-06). "Well Isn't That Qt". Archived from the original on 2010-04-09. Retrieved 2010-02-12.
- Chris Wilson (2009-08-31). "Cool Stuff". Retrieved 2010-02-12.
- Bas Schouten (2009-11-22). "Direct2D: Hardware Rendering a Browser". Retrieved 2010-02-12.
- Larabel, Michael (2022-02-27). "Cairo graphics library drops many old backends". Phoronix. Retrieved 2022-06-05.
- "GNOME/librsvg". GitHub.
- "GTK+ to Use Cairo Vector Engine". Retrieved 2009-12-27.
- "Details of package gtk-vector-screenshot in stretch". Debian. GitHub
- "Mono - Drawing". Retrieved 2009-12-27.
- "Moonlight Notes". Retrieved 2009-12-27.
- "Gecko 1.9 Roadmap". Retrieved 2009-12-27.
- "ReleaseNotes046". Inkscape Wiki. Retrieved 2008-03-31.
- "ManimCE tutorial by TheoremOfBeethoven — ManimCE tutorial by TB documentation". zavden.github.io. Retrieved 2023-01-29.
- "Gnuplot version 4.4.0 announcement". Gnuplot homepage. Archived from the original on 2011-05-14. Retrieved 2011-02-22.
- "Mailing list thread about the Cairo name change". 15 July 2003. Retrieved 2009-06-08.
- "Mailing list thread about the Cairo name change". 12 July 2003. Retrieved 2006-12-02.
- "Text". Readthedocs. Retrieved 2022-03-11.
External links

- Official website
- cairocffi on GitHub – CFFI-based Cairo bindings for Python
- "Cairo API reference manual".
- "Cairo here, there and everywhere". Linux.Ars. Ars Technica. 23 August 2005.
- "Cross-platform graphics with cairo". IBM.
- "Comparison of PHP image libraries".
- "The Cairo graphics tutorial".