2009-10-29

Creating a Visual Studio 2008 application that uses Cairo

One day or another, you'll want to produce quick 2D data with your code for visualization, and after looking through hordes of libraries that do not satisfy your needs at all (listen, it's not that hard: I don't want graphing, I don't want 3D, and I certainly don't want proprietary closed source paying software! I just want something that gives me a simple canvas to draw elementary stuff like text fields or simple graphics using 2D coordinates), you'll settle down on Cairo as the best trade-off for quick and easy generic 2D output. If it's used by Firefox for SVG output, it certainly should satisfy our needs.

Unfortunately, or should I say, as usual, whenever you want a nice step by step tutorial on how to get you started with using Cairo on Windows, you'll get nothing but a handful of incomplete snippets here and there. This short step by step tutorial attempts to remedy that.

For this exercise, we'll just create a C console application that outputs "Hello, World" to a PNG file using Cairo using Visual Studio 2008.

  1. Create a new Win32 Console Application in Visual Studio. Let's call it cairo_test. And since we don't wanna get bogged down by Microsoft's crap on a simple hello world app, on Application Settings -> Additional Options, make sure you check "Empty Project".

  2. Create a new source file - let's call it main.c - and fill it with the following content (which I picked up from here):
    #define LIBCAIRO_EXPORTS

    #include <cairo/cairo.h>

    int main(int argc, char** argv)
    {
    cairo_surface_t *surface;
    cairo_t *cr;

    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 240, 80);
    cr = cairo_create (surface);

    cairo_select_font_face (cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
    cairo_set_font_size (cr, 32.0);
    cairo_set_source_rgb (cr, 0.0, 0.0, 1.0);
    cairo_move_to (cr, 10.0, 50.0);
    cairo_show_text (cr, "Hello, World");
    cairo_destroy (cr);
    cairo_surface_write_to_png (surface, "hello.png");
    cairo_surface_destroy (surface);

    return 0;
    }
    Don't worry about the "#include <cairo.h>" for now, we'll sort it out in a second

  3. Download the latest Cairo Dev package files for Windows from http://www.gtk.org/download.html by picking up either Windows 32 or 64. At the time of this article, the latest Dev is cairo 1.8.8.
    Extract the package directories "lib" and "include" at the root of your Visual Studio project. You can safely ignore the other directories from the archive.

  4. Change the Active configuration if needed and right click on your project in the Solution Explorer panel to access the properties page.
    • In Configuration Properties -> C/C++ -> Additional Include Directories, create a new entry and point it to "<your project root>\include". Be mindful that there is a cairo subdirectory there, which is why we used cairo/cairo.h in our source. Just make sure the source and your include paths match.
    • In Configuration Properties -> Linker -> Input -> Additional Dependencies, type "cairo.lib"
    • In Configuration Properties -> Linker -> Gener al -> Additional Library Directories, create a new entry and point it to the "<your project root>\lib" directory you extracted above. (Oh, and why oh why are the Additional Dependencies and Additional Library Directories on 2 different pages Microsoft?!? Where's the twisted UI logic behind that?)

  5. Try to compile your project. It should complete without errors. Note that if you picked up the Windows 64 libraries, you MUST create a new x64 configuration, or the process will fail with "fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'X86'". Just follow these guidelines if you don't know how to do that.

  6. Bet you didn't wait and tried to run your executable already. And of course, you got the DLL not found errors. Why of course, now you need to install the bunch of DLLs Cairo needs to be happy. Basically, what you should do is pick up the DLLs from ALL the binary packages below (still provided by the GTK+ Windows 32 or Windows 64 Project binaries) and extract them into the Release or Debug directory that contains your executable. For all of the archives, you j ust need to extract the DLL - all the other files are irrelevant:
    • cairo Binaries (yes you need the binaries package too, as the Dev one doesn't contain the DLL) -> libcairo-2.dll
    • zlib Binaries -> zlib1.dll
    • libpng Binaries -> libpng12-0.dll
    • Freetype Binaries -> freetype6.dll
    • FontConfig Binaries -> libfontconfig-1.dll
    • expat Binaries -> libexpat-1.dll
    If you're gonna produce JPEG or TIFF images with your application, you probably want to install those DLLs too, but you already guessed that.

  7. Now you can actually run your test program. It should produce an "hello.png" file that looks like the one below:

Alrighty then. Now you can get going and visualize the hell out of whatever ground-breaking application you've been thinking of!

1 comment:

  1. Thanks for this. Helped me quite a bit. I found that cairo.lib wasn't in the main GTK dev package I got (only libcairo.dll.a, which wasn't enough), and I had to get it separately from the GTK win32 page, where it lays out each package separately. Once I got over that it was pretty straightforward.

    ReplyDelete