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.