Whole document tree
Once SVPs have been generated from ArtVPaths and ArtBPaths, you need to do the actual rasterization into pixel buffers. This step can be done with three routines: art_rgb_svp_aa, art_rgb_svp_alpha or art_gray_svp_aa. There also exist a low-level API for rasterizing, art_svp_render_aa. For conveniance, libart also provides some simple functions to fill pixel buffers with background colors such as art_rgb_fill_run and art_rgb_run_alpha
Each of the three high-level function used for rendering represents pixel buffers by two parameters: a rowstride and pointer to an array of art_u8. The exact semantics of these parameters depend of course on the nature pixel buffer (namely, the semantics are slightly different for B&W and color pixel buffers) but the spirit is the same. An image is represented by the list of the values of each of its pixels. Libart manipulates only images where each such pixel value is coded on 8 bits (that is, a byte/octet): this does not harm libart's usefulness since this is the most widely used format both in software and hardware. For example, a 256x256 B&W image will use 256 * 256 = 65536 bytes and a color image will use 256 * 256 * 3 = 196608 bytes (because in a color image, we code separatly the red, green and blue components of the image, each on 8 bits).
It is a natural idea to store these pixels one after the other, building a pixel buffer which is represented by the art_u8 array (pixels are listed from left to right/top to bottom). Once you know the kind of pixel you are using (either B&W or color), all you need to know to parse efficiently the buffer is to know the width of the original image (so that you can jump from line to line). It happens that people are used to represent this information with rowstrides. The rowstride of our 256x256 B&W image is 256: it is the number of bytes a row of the image needs to be stored.
Code to use the three rendering functions can be found in the previous examples. The only thing you need to take care of when using them is to make sure the rendering area defined by (x0,y0,x1,y1) is smaller than the pixel buffer where the vector paths are to be rendered (otherwise, bad segfaults will happen).
Finally, users who want to do cool rendering (such as filling a vector path with a pattern or a gradient instead of using a solid color should look into librsvg. librsvg is a library used by nautilus to render svg graphics which extends libart and provides a number of rendering functions using the low-level art_rgb_run_alpha function. It should be noted that librsvg contains code from the unstable branch of libart_lgpl which was backported to the stable libart but not included in it because of binary compatibility.). Users could also write their own rendering callbacks with art_rgb_run_alpha but doing so requires a lot of knowledge of the internals of libart: if you really want to do this, read the section Libart Internals.
Fills a buffer with n copies of the (r, g, b) triple. Thus, locations buf (inclusive) through buf + 3 * n (exclusive) are written.
The implementation of this routine is very highly optimized.
Renders a sequential run of solid (r, g, b) color over buf with opacity alpha.
Renders the shape specified with svp into the buf RGB buffer. x1 - x0 specifies the width, and y1 - y0 specifies the height, of the rectangle rendered. The new pixels are stored starting at the first byte of buf. Thus, the x0 and y0 parameters specify an offset within svp, and may be tweaked as a way of doing integer-pixel translations without fiddling with svp itself.
The fg_color and bg_color arguments specify the opaque colors to be used for rendering. For pixels of entirely 0 winding-number, bg_color is used. For pixels of entirely 1 winding number, fg_color is used. In between, the color is interpolated based on the fraction of the pixel with a winding number of 1. If alphagamma is NULL, then linear interpolation (in pixel counts) is the default. Otherwise, the interpolation is as specified by alphagamma.
Renders the shape specified with svp over the buf RGB buffer. x1 - x0 specifies the width, and y1 - y0 specifies the height, of the rectangle rendered. The new pixels are stored starting at the first byte of buf. Thus, the x0 and y0 parameters specify an offset within svp, and may be tweaked as a way of doing integer-pixel translations without fiddling with svp itself.
The rgba argument specifies the color for the rendering. Pixels of entirely 0 winding number are left untouched. Pixels of entirely 1 winding number have the color rgba composited over them (ie, are replaced by the red, green, blue components of rgba if the alpha component is 0xff). Pixels of intermediate coverage are interpolated according to the rule in alphagamma, or default to linear if alphagamma is NULL.
Each pixel gets a value proportional to the area within the pixel overlapping the (filled) SVP. Pixel (x, y) is stored at:
buf[(y - * y0) * rowstride + (x - x0)]
All pixels x0 <= x < x1, y0 <= y < y1 are generated. A stored value of zero is no coverage, and a value of 255 is full coverage. The area within the pixel (x, y) is the region covered by [x..x+1] and [y..y+1].
Renders the sorted vector path in the given rectangle, antialiased.
This interface uses a callback for the actual pixel rendering. The callback is called y1 - y0 times (once for each scan line). The y coordinate is given as an argument for convenience (it could be stored in the callback's private data and incremented on each call).
The rendered polygon is represented in a semi-runlength format: a start value and a sequence of "steps". Each step has an x coordinate and a value delta. The resulting value at position x is equal to the sum of the start value and all step delta values for which the step x coordinate is less than or equal to x. An efficient algorithm will traverse the steps left to right, keeping a running sum.
All x coordinates in the steps are guaranteed to be x0 <= x < x1. (This guarantee is a change from the gfonted vpaar renderer from which this routine is derived, and is designed to simplify the callback).
The value 0x8000 represents 0% coverage by the polygon, while 0xff8000 represents 100% coverage. This format is designed so that >> 16 results in a standard 0x00..0xff value range, with nice rounding.