Matt wrote
Implement it piecemeal then. Work on specific features (lines, shapes, paths,
clipping), then move on to the more difficult stuff (transforms, line styles,
etc.)
Matt
Actually Matt, the transforms are the simplest thing. Its just
linear algebra, and matrix math. Anyways, the basic deal is this, I’ve
finished a working vector graphics package! The antialiasing needs a
little work, but it’s nothing one couldn’t fake with a nice quick rle
blur…
I did some research into look ahead optimization of bezier curve
rasterization, and basically I’ve decided to go for simplicity. I’ve
broken every bezier curve into 1000 vectors. This is roughly what
libart does, and it gives you decent curves. Since the length of any
curve is unlikely to be more than 3000 at 1024 x 768, the typical
vector is much less than 3 pixels long. Most curves however, have
10s of vectors per pixel, which means it is very fine grained indeed.
The vector structure which makes up all paths is as follows:
typedef struct vector *Vector;
enum drawable { line, bezier, not };
struct vector {
enum drawable type;
double x,y,u,v;
Vector next;
}
As you will undoubtly have noticed, all vectors form nice linked lists.
Hence a path is little more than a list of vectors, and a scratch SDL
surface for rendering.
If the vector is a bezier, that indicates it is the start of a three
vector list which describes the control points for the curve. Naturally
the two vectors after a bezier are of type “not” and as simply not drawn.
I have three cases for drawing a vector:
width = 1
width = 2
width > 2
The first case draws one line, the second three lines, and the last
four bounding lines and then does a recusive flood_fill to fill the
contents. This is reasonably fast a a P75, but I’m sure it can be
optimized in the future.
When a path is painted, it is painted to an SDL surface, and its
values are technically the alpha levels. Then to draw that curve
onto anther surface, like the screen, it uses a selective blit command
preforming an alpha blend between the existing image, and any color or
source image specified, using the path’s SDL_Surface as an Alpha mask.
This lets one selectively copy from one image to another, along a path.
(ie you can use it to copy non-rectangle shapes) or simply draw solid
color, with transparency.
I will be releasing the code probably on Sunday after I finish off the
Forth based scripting engine / language. I hope to make it Adobe
Postscript compatible for the most part, but I doubt in this release
it will cover anything more than
newpath
moveto
lineto
rlineto
curveto
rcurveto
stroke
and also
image
set-line-width
set-line-color
set-line-alpha
and a set line width, and set color options… I’ll probably add image
suppport through SDL_image (because that’ll be simple). In the end
however it will be a fully functional programming language, with the
ability to load new modules, like python or perl. So chances are
it will be ultimately known SDLscript or something like that.