[cairo] [cairo-announce] cairo snapshot 1.3.2 now available
jonathon.jongsma at gmail.com
Thu Jan 18 21:01:03 PST 2007
On 1/17/07, Carl Worth <cworth at cworth.org> wrote:
> Ah, so that's yet another difference.
> Here's a summary that includes both the difference I was talking
> about, as well as the one you were talking about:
> Allocates an array for the user, and also allocated a
> containing object that contains a pointer to the array as well
> as the size. The returned object must be destroyed with
> Fills in an array that is provided by the user, (so no
> function is provided to destroy anything since cairo isn't
> allocating anything). But cairo does provide
> cairo_get_dash_count so that the user can allocate the array
> in the first place.
> Fills in pointers to several values corresponding to a single
> color stop. This function must be called several times in
> order to obtain the complete set of color stops, (and cairo
> provides cairo_get_color_stop_count so the user can know how
> many times to call the function).
> I don't think those differences are good, (even if I can even answer
> _why_ some of them exist).
> For example, the distinction between get_dash and get_color_stop is
> that get_dash is filling in an array of native doubles, (and the same
> array is used by set_dash). But with get_color_stop, you have the
> flexibility to use it to fill in any custom structure you might have
> that has color stop values in it, (that is without any additional
> copying). You would still need a loop around that to get them all, but
> you also need the same look to call cairo_pattern_add_color_stop. Is
> that a good optimization or just an API gaffe?
Speaking from the C++ perspective, I found the cairo_get_color_stop
API the easiest to wrap and the copy_clip_rectangles() API was quite
awkward. I'll try to give my impressions quickly.
First, I'd just like to note that in cairomm, I try to use standard
C++ containers wherever possible in preference to plain C arrays and
such, with the assumption that if the user does not want to pay the
costs associated with using these containers, they can always use the
C api directly.
The problem with the copy_clip_rectangles() API is that cairo
allocates a C array for you and in order to get it into a standard C++
container, you have two basic options:
A) copy all of the elements into the container, or
B) create an ugly wrapper class that simulates a standard C++ container
The problem with A is obvious: cairo has already allocated and copied
all of the values into its own array structure, and we're copying them
again into our structure. So we've added an unnecessary copy. As far
as B is concerned, gtkmm/glibmm has wrapper classes that do this
(Glib::ArrayHandle), but from experience we've learned that they tend
to confuse the user and they're difficult to get right. So I'd really
like to avoid a custom wrapper class. Ideally, I'd love to have
access to the 'pre-copied' data so that I could copy it into whatever
structure I want and not need to do so much unnecessary copying to get
it into my container of choice.
The get_dash() API is actually very similar to the
copy_clip_rectangles() API from a C++-binding perspective. Since it
also expects the data to be put into a plain C array, a C array must
still be allocated, the main difference is that now the binding is
responsible for the allocation instead of cairo itself.
The get_color_stop() API is actually quite nice from a C++-binding
perspective, because it doesn't make any assumptions about the final
array structure and lets me put them one-by-one into whatever
structure I'd like.
Granted, the very thing that makes the get_color_stop() API the
easiest to wrap is its flexibility, which also probably makes it the
most difficult of the three interfaces to use directly from C. So I'm
not sure what the correct answer is.
More information about the cairo