Google

NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.52">

Sample code


A non-displaying application

To get a good idea on how to use libart in your own application, here is a simple example which does nothing but render in a pixel buffer a small square. The full source for this example is available for download: art-non-diplay.tar.gz (includes a simple Makefile to build it).

int main (int argc, char *argv[])
{
  ArtSVP *path;
  char *buffer;

  path = make_path ();

  buffer = render_path (path);

  save_buffer (buffer, "foo.png");

  return 0;
}
      

As shown above, we begin by creating an SVP, then we render it in a pixel buffer and last we save it to a file. Creating the SVP is very easy:

static ArtSVP *
make_path (void)
{
  ArtVpath *vec = NULL;
  ArtSVP *svp = NULL;
  
  vec = art_new (ArtVpath, 10);
  vec[0].code = ART_MOVETO;
  vec[0].x = 0;
  vec[0].y = 0;
  vec[1].code = ART_LINETO;
  vec[1].x = 0;
  vec[1].y = 10;
  vec[2].code = ART_LINETO;
  vec[2].x = 10;
  vec[2].y = 10;
  vec[3].code = ART_LINETO;
  vec[3].x = 10;
  vec[3].y = 0;
  vec[4].code = ART_END;

  svp = art_svp_from_vpath (vec);

  return svp;
}

The above VPath is a list of drawing commands. There are 5 different drawing commands: ART_MOVETO, ART_MOVETO_OPEN, ART_LINETO, ART_CURVETO an ART_END.

  • ART_MOVETO and ART_MOVETO_OPEN describe where the pen of the painter starts to draw the vectors. ART_MOVETO starts a closed vector path (the last point of the vector path will be connected to the first one).

  • ART_END ends a vector path.

  • ART_LINETO and ART_CURVETO describe the following point in the vector path. ART_CURVETO is reserved for use with BPaths and cannot be used with a Vpath.

The following figure summarizes the behaviour of these drawing commands:

Figure 1. Drawing commands

Once the SVP is built, we render it and save it to a file:

static unsigned char *
render_path (const ArtSVP *path)
{
  art_u8 *buffer = NULL;
  art_u32 color = (0xFF << 24) | (0x00 <<16) | (0x00<<8) | (0xFF) ; /* RRGGBBAA */
    

  buffer = art_new (art_u8, WIDTH*HEIGHT*BYTES_PER_PIXEL);
  art_rgb_run_alpha (buffer, 0xFF, 0xFF, 0xFF, 0xFF, WIDTH*HEIGHT);
  art_rgb_svp_alpha (path, 0, 0, WIDTH, HEIGHT, 
		     color, buffer, ROWSTRIDE, NULL);

  return (unsigned char *) buffer;
}

static void
save_buffer (const unsigned char *buffer, const char *filename)
{
  GdkPixbuf *pixbuf;

  pixbuf = gdk_pixbuf_new_from_data (buffer,
				     GDK_COLORSPACE_RGB, 
				     FALSE, 8,
				     WIDTH, HEIGHT,
				     ROWSTRIDE,
				     NULL, NULL);

  pixbuf_save_to_file (pixbuf, filename);
 
  gdk_pixbuf_unref (pixbuf);
}

The rendering is itself pretty simple: we first fill the buffer with the 0xFFFFFFFF rgba color (that is, 0xFFFFFF rgb color with a transparency of 0xFF which means no transparency at all. It should be called opacity actually ;) with the art_rgb_run_alpha function. Then, we fill the svp in the buffer with the 0xFF0000FF rgba color with the art_rgb_svp_alpha function.

Last, to save the pixel buffer, we just instantiate a GdkPixbuf and save it with the pixbuf_save_to_file function we stole from random pieces of code (namely, nautilus and gnome-iconedit).

Easy, was it not ?