[cairo] PDF Backend for cairo
Kristian Høgsberg
krh at bitplanet.net
Mon Nov 29 11:59:09 PST 2004
Hi,
I've been working on a PDF backend for cairo over the weekend, and at
this point I think it's appropriate post a snapshot of the current code.
It's not based on Ross McFarlands patch, I only thought to search for
previous work after working on it for a day. I think my approach is a
little further along now than Ross's code, except I think Ross had some
support for alpha channels done.
The current snapshot supports:
- opaque, solid filled polygons
- linear and radial gradient filled polygons
- image compositing
On the top of my TODO list is:
- transparency
- clipping
- fix the polygon bug evident in snippets.pdf
- text
- surface patterns
- figure out how to make sense of the x_ppi and y_ppi arguments to
cairo_pdf_surface_create()
I've run the cairo snippets test case for PDF and the result can be
inspected here:
http://people.redhat.com/krh/cairo-pdf/snippets.pdf
Compare with:
http://cairographics.org/samples/
So far the backend API works pretty well, though there are a couple of
issues to discuss. I haven't thought about this too much, I'm just
throwing out a couple of ideas:
Right now the PDF backends only render the trapezoids cairo passes it
after tesselation. PDF has the same curve_to and line_to operators as
cairo has and could do stroking and filling if it was passed the
highlevel path instead of the tesselation output. I think this could be
acheived by adding stroke_path() and fill_path() function pointers to
the cairo_surface_backend_t struct, something along these lines:
cairo_int_status_t
(*stroke_path) (void *dst,
cairo_surface_t *src,
cairo_operator_t operator,
int xSrc,
int ySrc,
cairo_path_t *path,
[ gstate ]);
cairo_int_status_t
(*fill_path) (void *dst,
cairo_surface_t *src,
cairo_operator_t operator,
int xSrc,
int ySrc,
cairo_path_t *path,
[ gstate ]);
where [ gstate ] means that the current line cap, line join, line width,
fill rule etc should be passed to the backend. I'm not sure what the
best approach would be: either just pass the relevant part of the state
in the call or let the backend query the gstate object directly.
cairo_gstate_t isn't exposed to the backends elsewhere, so I'm thinking
that's not a good idea. The cairo core would call these functions
before tesselating and if they return other than CAIRO_STATUS_SUCCESS,
cairo falls through to the cairo tesselator. This is basically how the
other backend hooks work.
The other issue is that whenever an image surface is composited it is
embedded into the stream. This is not a problem for one-off images but
if you use the same image several times the image data is duplicated in
the stream. This is a problem with gradients as well, where the
gradient definition is written each times it is used. Part of this can
be solved in the PDF backend by remembering the resource ID for a
surface and reusing that if the surface is used again. Except if the
surface has been changed in the meantime, in which case the new image
data must be written to the file. This could be worked around by
storing a hash of the image data with the resource ID, but I was
thinking about adding a generation field to the surface. Everytime the
surface is altered the generation is increased, making it easy for
backends to determine if it safe to reuse previous resources.
cheers,
Kristian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cairo-pdf.patch
Type: text/x-patch
Size: 32547 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20041129/2d43542f/cairo-pdf.bin
More information about the cairo
mailing list