# libvega module

$Id$

## Introduction

### General description

libvega is a library for vector graphics used in Opera. Both SVG and canvas uses this module. It includes paths with fill and stroke, transforms, image and gradient fills and filters.
Libvega also contains the code for the canvas and a painter.
In order to use the hardware acceleration functionality of libvega the 3ddevice interface must be implemented by the platform. There is a reference gl implementation which should be used and extended for OpenGL support.

### Use-case: draw vector graphics using SVG or canvas

When the used loads a page containing SVG or canvas the SVG module or canvas code will parse the input and issue draw command. Theses commands are sent to libvega which draws them to the screen.

### Design goals

The design goals of libvega are:

- Be as fast as possible
- Use as little memory as possible
- Support all features required for SVG and canvas
- Support acceleration of draing with hardware through OpenGL or similar
- Have support for OpPainter which can render Opera

### Supported standards

libvega does not implement a standard, but it contains functions needed to render SVG and canvas draw operations.

## API documentation

The API documentation is generated by Doxygen.

## Memory handling

### OOM handling

OOM is signaled through OpStatus. TRAP/LEAVE is not used in this module. When an OOM occurs OpStatus::ERR_NO_MEMORY is propagated back to the entry point. It is assumed that the caller handles the OOM.

### Memory usage

#### Stack

There is not recursion in the libvega module, keeping stack usage very low.

#### Heap

libvegas software render targets requires a pointer to the data of a bitmap. This means that a large block must be allocated if the OpBitmap does not support pointers.
Paths in libvega are translated to lines as soon as they are added. This requires much memory for paths with many curves, specially if they are outlined.

#### Static

There are not static arrays in libvega.

#### Freeing

Most objects in libvega are allocated by external code, and that code is also responsible for freeing the data.
The calling code is also responsible for freeing data allocated by the VEGARenderer's create functions.

### Future improvements

The path code should be rewritten to store curves rather than lines for as long as possible.

## Implementation details

libvega consists of many classes which are used together to draw images.
The path contains all shapes to be drawn.
The renderer fills paths and creates most of the required objects such as render targets, paths and fills. It does not create paths and transforms.
A render target is a target for rendering bound either to an OpBitmap or to nothing if it is just an intermediate render target used only be libvega.
The stencil is used as clipping by the renderer, but it is also a render target
The fills (pattern and gradient) are used by the renderer to fill the shape.
The filters operate on render targets and manipulate the destination according to the filter type and source data.

Rendering in vega is done to a render target. A render target is an abstract framebuffer. It can be an OpBitmap or a data arry in software. The main reason for using render targets is to support rendering with a 3d device. In this case the render target is a texture or a window which can be rendered to using render to texture.

The antialiasing in vega is based on multisampling. The alpha value is created based on a number of samples depending on the quality setting. The color is then calculated at the center of the pixel and blended to the render target using the calculated (by number of covering samples) alpha value.
In order to check which samples in the pixel are covered, the lines needs to be sorted from left to right. The scanline is then check from left to right and the inside/outside properties are updated based on the number of entries and exits to/from the shape.
Previous versions used quicksort for this sorting, but since the current method is based on multisampling it is possible to sort using bucket sort. This gives us a pure linear software backend.