[cairo] API Shakeup: cairo_output_stream_t and cairo_surface_finish()

Carl Worth cworth at cworth.org
Wed Mar 16 08:33:54 PST 2005


On Tue, 01 Mar 2005 22:25:05 -0500, Kristian Høgsberg wrote:
> Hmm, I see what you mean.  I did pick the current ordering for a reason, 
> though, but didn't consider consistency between these two functions. 
> What I was thinking was that with cairo_surface_set_user_data(), you're 
> attaching a piece of data to a surface.  The destroy notifier is a less 
> important detail, and thus comes later in the argument list.  It's what 
> g_object_set_data() from glib does.
> 
> For cairo_pdf_surface_create() it's the other way around; the important 
> information is write_func, while the closure data is a detail required 
> to implement it.

I agree with that much. The next question though is what to do with
the destroy notifier for the pdf_surface_create. Do we follow the same
logic and put it after write_func/closure? That would give:

   cairo_surface_t *
   cairo_pdf_surface_create (cairo_write_func_t    write_func,
                             void                  *closure,
                             cairo_destroy_func_t  destroy_closure_func,
                             double                width_inches,
                             double                height_inches);

But that looks pretty ugly since we've now got multiple function calls
accepting a common closure, but not grouped before that closure in the
argument list. So, I guess this rule should trump the other. So I'll
now agree with the original ordering:

   cairo_surface_t *
   cairo_pdf_surface_create (cairo_write_func_t    write_func,
                             cairo_destroy_func_t  destroy_closure_func,
                             void                  *closure,
                             double                width_inches,
                             double                height_inches);

> Here I agree, the closure should be at the same position in the argument 
> list in all cases.  Again, I was taking a clue from glib which always 
> pass the closure argument as the last argument.  If you want it as the 
> first argument, then that's what we do.

Yes, let's do "closure, data, length" ordering. That puts the object
being operated on first, and it matches the order of write(). (It
doesn't match fwrite, but that one as always annoyed me anyway---it's
already inconsistent with its friends like fprintf).

> > And should data really be a "void *" rather than "char *". Otherwise,
> > what does length mean?
> 
> This is what write() takes.  Also, read, memcpy, memset all take void 
> pointers and byte counts.  Given a void pointer and a "length" would you 
> assume anything else than bytes?  Of course this should be documented (a 
> detail I left out in my documentation).

OK. But if "char *" wouldn't inflict a bunch of painful casts on
users, then it might be preferable. The current proposal makes the
user write a function with two "void *" parameters which seems to be
setting them up to make mistakes.

So, my vote would be:

typedef cairo_status_t (*cairo_write_func_t) (void	   *closure,
					      const char   *data,
					      unsigned int  length);

> >>   cairo_finish (cairo_t *cr);
> > 
> > I may have originally proposed this function, but as I mentioned in
> > the separate cairo_surface_finish thread, I now think it's a
> > gratuitous convenience function that we should eliminate.
> 
> Couldn't you say the same about cairo_show_page() and cairo_copy_page()?

Yes. Let's leave it for now, and I'll think about gutting them
(consistently) later.

-Carl
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20050316/6be5c323/attachment.pgp


More information about the cairo mailing list