The libart library
<<< Previous Page | Home | Up | Next Page >>>

# Svp rendering

## Name

Svp rendering -- How to actually render SVPs into pixel buffers.

## Synopsis

    void        art_rgb_fill_run                (art_u8 *buf,
                                                 art_u8 r,
                                                 art_u8 g,
                                                 art_u8 b,
                                                 int n);
    void        art_rgb_run_alpha               (art_u8 *buf,
                                                 art_u8 r,
                                                 art_u8 g,
                                                 art_u8 b,
                                                 int alpha,
                                                 int n);
    void        art_rgb_svp_aa                  (const ArtSVP *svp,
                                                 int x0,
                                                 int y0,
                                                 int x1,
                                                 int y1,
                                                 art_u32 fg_color,
                                                 art_u32 bg_color,
                                                 art_u8 *buf,
                                                 int rowstride,
                                                 ArtAlphaGamma *alphagamma);
    void        art_rgb_svp_alpha               (const ArtSVP *svp,
                                                 int x0,
                                                 int y0,
                                                 int x1,
                                                 int y1,
                                                 art_u32 rgba,
                                                 art_u8 *buf,
                                                 int rowstride,
                                                 ArtAlphaGamma *alphagamma);
    void        art_gray_svp_aa                 (const ArtSVP *svp,
                                                 int x0,
                                                 int y0,
                                                 int x1,
                                                 int y1,
                                                 art_u8 *buf,
                                                 int rowstride);
    struct      ArtSVPRenderAAStep;
    void        art_svp_render_aa               (const ArtSVP *svp,
                                                 int x0,
                                                 int y0,
                                                 int x1,
                                                 int y1,
                                                 void (*callback) (void *callback_data,int y,int start,ArtSVPRenderAAStep *steps, int n_steps),
                                                 void *callback_data);

## Description

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.

## Details

### art_rgb_fill_run ()

    void        art_rgb_fill_run                (art_u8 *buf,
                                                 art_u8 r,
                                                 art_u8 g,
                                                 art_u8 b,
                                                 int n);

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.

`buf` : | Buffer to fill.
`r` : | Red, range 0..255.
`g` : | Green, range 0..255.
`b` : | Blue, range 0..255.
`n` : | Number of RGB triples to fill.

### art_rgb_run_alpha ()

    void        art_rgb_run_alpha               (art_u8 *buf,
                                                 art_u8 r,
                                                 art_u8 g,
                                                 art_u8 b,
                                                 int alpha,
                                                 int n);

Renders a sequential run of solid (`r`, `g`, `b`) color over `buf` with opacity `alpha`.

`buf` : | Buffer for rendering.
`r` : | Red, range 0..255.
`g` : | Green, range 0..255.
`b` : | Blue, range 0..255.
`alpha` : | Alpha, range 0..256.
`n` : | Number of RGB triples to render.

### art_rgb_svp_aa ()

    void        art_rgb_svp_aa                  (const ArtSVP *svp,
                                                 int x0,
                                                 int y0,
                                                 int x1,
                                                 int y1,
                                                 art_u32 fg_color,
                                                 art_u32 bg_color,
                                                 art_u8 *buf,
                                                 int rowstride,
                                                 ArtAlphaGamma *alphagamma);

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`.

`svp` : | The source sorted vector path.
`x0` : | Left coordinate of destination rectangle.
`y0` : | Top coordinate of destination rectangle.
`x1` : | Right coordinate of destination rectangle.
`y1` : | Bottom coordinate of destination rectangle.
`fg_color` : | Foreground color in 0xRRGGBB format.
`bg_color` : | Background color in 0xRRGGBB format.
`buf` : | Destination RGB buffer.
`rowstride` : | Rowstride of `buf` buffer.
`alphagamma` : | ArtAlphaGamma for gamma-correcting the rendering.

### art_rgb_svp_alpha ()

    void        art_rgb_svp_alpha               (const ArtSVP *svp,
                                                 int x0,
                                                 int y0,
                                                 int x1,
                                                 int y1,
                                                 art_u32 rgba,
                                                 art_u8 *buf,
                                                 int rowstride,
                                                 ArtAlphaGamma *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.

`svp` : | The source sorted vector path.
`x0` : | Left coordinate of destination rectangle.
`y0` : | Top coordinate of destination rectangle.
`x1` : | Right coordinate of destination rectangle.
`y1` : | Bottom coordinate of destination rectangle.
`rgba` : | Color in 0xRRGGBBAA format.
`buf` : | Destination RGB buffer.
`rowstride` : | Rowstride of `buf` buffer.
`alphagamma` : | ArtAlphaGamma for gamma-correcting the compositing.

### art_gray_svp_aa ()

    void        art_gray_svp_aa                 (const ArtSVP *svp,
                                                 int x0,
                                                 int y0,
                                                 int x1,
                                                 int y1,
                                                 art_u8 *buf,
                                                 int rowstride);

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].

`svp` : | The SVP to render.
`x0` : | The view window's left coord.
`y0` : | The view window's top coord.
`x1` : | The view window's right coord.
`y1` : | The view window's bottom coord.
`buf` : | The buffer where the bytemap is stored.
`rowstride` : | the rowstride for `buf`.

### struct ArtSVPRenderAAStep

    struct ArtSVPRenderAAStep {
      int x;
      int delta; /* stored with 16 fractional bits */
    };

### art_svp_render_aa ()

    void        art_svp_render_aa               (const ArtSVP *svp,
                                                 int x0,
                                                 int y0,
                                                 int x1,
                                                 int y1,
                                                 void (*callback) (void *callback_data,int y,int start,ArtSVPRenderAAStep *steps, int n_steps),
                                                 void *callback_data);

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.

`svp` : | The ArtSVP to render.
`x0` : | Left coordinate of destination rectangle.
`y0` : | Top coordinate of destination rectangle.
`x1` : | Right coordinate of destination rectangle.
`y1` : | Bottom coordinate of destination rectangle.
`callback` : | The callback which actually paints the pixels.
`callback_data` : | Private data for `callback`.

<<< Previous Page | Home | Up | Next Page >>>
SVPs | Known problems