[cairo] Separating Cairo from stdio.h

Ned Konz ned at squeakland.org
Mon Nov 1 09:58:06 PST 2004


Hi all,

This is similar to my prior mail about the dependency between libcairo and 
fontconfig.

The routines cairo_ps_surface_create() and cairo_png_surface_create() (and 
their corresponding set_target routines) assume that FILEs exist. However, I 
can see using these in systems without stdio.h or using them to create 
Postscript or PNG data in memory buffers or into a socket stream (perhaps in 
systems where you can't make FILEs out of socket handles).

Though there are conditionals (CAIRO_HAS_PS_SURFACE and CAIRO_HAS_PNG_SURFACE) 
around these, these functions would be useful with other kinds of streams 
(for instance, for generation of PNG images in a web server).

Looking at the code in cairo_ps_surface.c, I see that the file is indeed a 
pure, non-seekable stream.

In cairo_png_surface.c I see that the file is just being passed to libpng, 
which lets its users use other I/O routines at runtime using 
png_set_???_fn(), and also lets you compile libpng using the PNG_NO_STDIO 
define and just create PNG structures in buffers.

I would like to see additional/replacement functions for Postscript output at 
a somewhat more abstract level that allow for different kinds of Postscript 
surfaces, not only ones that are connected to FILE*s. And I would take the 
routines that take FILE* arguments and bracket them in conditionals that 
would let us compile libcairo without stdio.h.

I would also like to do the same thing for PNG surfaces.

I could see having the following flavors of surfaces (for PNG, Postscript, 
SVG, etc.):

* connected to a FILE*

* parameterized with one or more function pointers for a stream backend, along 
with user-specified arguments. Perhaps something like:

typedef cairo_status_t (cairo_surface_open_func_t) (void *closure);
typedef cairo_status_t (cairo_surface_write_func_t) (void *closure, const char 
*bytes, size_t byteSize);
typedef cairo_status_t (cairo_surface_close_func_t) (void *closure);

cairo_surface_t *cairo_png_surface_create(
 cairo_surface_open_func_t *opener,
 cairo_surface_write_func_t *writer,
 cairo_surface_close_func_t *closer,
 void* closure,
 cairo_format_t format,
 int width,
 int height);

And then rename the existing cairo_png_surface_create() as:

cairo_surface_t *cairo_png_surface_create_for_file(FILE* file, cairo_format_t 
format, int width, int height);

Or if there are lots of users of cairo_png_surface_create() etc. then we could 
just make up new names.

Though this isn't on my critical path right now (and so won't get any of my 
time until it becomes painful), I thought I'd write the list to see what your 
thoughts are on this so if I do get around to changing it I won't make 
something that you're not interested in using.

Thanks,
-- 
Ned Konz
http://bike-nomad.com/squeak/



More information about the cairo mailing list