Bug 6895 - Iterator interface for accessing path data
Summary: Iterator interface for accessing path data
Status: RESOLVED MOVED
Alias: None
Product: cairomm
Classification: Unclassified
Component: General (show other bugs)
Version: CVS HEAD
Hardware: x86 (IA32) Linux (All)
: high normal
Assignee: Murray Cumming
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-05-12 13:08 UTC by Jonathon Jongsma
Modified: 2018-08-25 13:23 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments
patch to add Path iterator interface (8.43 KB, patch)
2006-05-12 13:09 UTC, Jonathon Jongsma
Details | Splinter Review
New example program to demonstrate new API (10.00 KB, application/octet-stream)
2006-05-12 13:10 UTC, Jonathon Jongsma
Details

Description Jonathon Jongsma 2006-05-12 13:08:00 UTC
Currently there's no way to access the path data without reverting to the C
struct and mucking around with pointers.  I'd like to have a more STL-like
iterator interface for this (which is also recommended in the Cairo bindings
guidelines: http://www.cairographics.org/manual/bindings-path.html).  I've been
playing around with a few ideas and hope to get some feedback on them.  For
background on the underlying C type, see
http://www.cairographics.org/manual/cairo-Paths.html#cairo-path-data-t

I'm attaching a patch and a tarball that contains a new example program to
demonstrate the new API.  This isn't polished by any means and I there may still
be large problems with it (and there almost definitely are many small problems
with it).  

Any feedback would be greatly appreciated.
Comment 1 Jonathon Jongsma 2006-05-12 13:09:52 UTC
Created attachment 5608 [details] [review]
patch to add Path iterator interface
Comment 2 Jonathon Jongsma 2006-05-12 13:10:51 UTC
Created attachment 5609 [details]
New example program to demonstrate new API
Comment 3 Murray Cumming 2006-05-12 16:26:19 UTC
Looks sensible, though I haven't thought about it in depth. These things are
never nice to implement, but we are lucky that the cairo developers have told us
what they want from the binding, and your API seems to be what is suggested.

I assume that this API is for examining the elements and their points, and _not_
for changing anything? We should maybe confirm that that is the intent of the C API.


Minor nitpicks:

These should be const:
Point operator[](unsigned int idx);
int size(void);
ElementType type(void);

And I generally use () instead of (void)
Comment 4 Jonathon Jongsma 2006-05-12 23:16:47 UTC
(In reply to comment #3)
> I assume that this API is for examining the elements and their points, and _not_
> for changing anything? We should maybe confirm that that is the intent of the
C API.

Yes, that's what I had assumed.  In Owen Taylor's recent response to the Path
RefPtr thread on the cairo mailing list he had referred to a path as an
'immutable type', so I assume that this is the intent of the C API.  

I really don't have a good idea about when the path data would be useful,
frankly, but I want to try to get complete coverage of the C API.

> Minor nitpicks:
> 
> These should be const:
> Point operator[](unsigned int idx);
> int size(void);
> ElementType type(void);
> 
> And I generally use () instead of (void)

Thanks.  One other thing that I'd like your opinion on since you have much more
experience than I do at wrapping C libraries:

This new API sort of implies that a Path is a container containing a set of
Path::Element objects.  So de-referencing a Path::iterator returns a reference
to a Path::Element object.  I haven't done much with custom iterators before,
but I would assume that in normal code (i.e. if you weren't constrained by
wrapping a C object), you'd have the iterator contain a pointer-to-Element and
have that interal pointer increment to point at the next Element in the list
when the iterator is advanced.  But I don't have a list of Element objects that
I can point at; I only have the underlying C array.

What I did instead was have Path::iterator own an instance of Element.  Since
Element has a data member which is a pointer to an item within the underlying C
array, I simply change this member to point at the next item in the underlying
array whenever the iterator is advanced (using the Element::reset() function). 
Then when I dereference the iterator, I return a reference to this object.  So
there's only one Element object ever instantiated, it just changes what it's
pointing at.

I'm not completely happy with this approach, but couldn't come up with a better
one.  Do you have any concerns / thoughts / ideas about it?  I thought about
trying to actually create a vector of Element objects, but I'm not sure whether
that's a good idea or not.

One big open question here is copying an Element -- should we allow copying? 
should the copy of Element point to the same underlying address as the original?
 or should the copy have its own copy of the data?  And if so, how would that
copied data get freed? Elements aren't responsible for freeing the data they
wrap; the path is all freed at once with cairo_path_destroy() (which is called
from ~Path()).  

Which brings up another question -- what if the Path object gets deleted while
we still have references to Element around?  they would now be pointing at
invalid data.
Comment 5 Murray Cumming 2006-05-13 01:57:58 UTC
> One big open question here is copying an Element -- should we allow copying? 

I don't think we need to, and we could add it later.

> what if the Path object gets deleted while we still have references to Element 
> around?  they would now be pointing at invalid data.

I think this is OK. It's like dereferencing an iter to a std::list and expecting
to use it after you have deleted the std::list.

I'll try to take another look soon.
Comment 6 Jonathon Jongsma 2006-05-26 00:46:33 UTC
Were you still planning to review this in more depth at some point, Murray?
Comment 7 Murray Cumming 2006-05-26 22:22:53 UTC
I'd pre-declare the cairo_path_data_t struct, to avoid including cairo.h in the
public header.

And I'd add a comment next to the Path::Element::Point struct saying that we are
reimplementing it just so we don't have to include the public header (and it
wouldn't be efficient to use accessor functions for such a simple struct).

The use of Path::Element::reset() does seem bad. For instance:
const Path::Element& element = *iter;
++iter;
//Now element has changed, but I didn't expect that.
Comment 8 Jonathon Jongsma 2006-05-30 17:21:28 UTC
what if I change Path::iterator::operator*() from 
      inline reference operator*() { return m_node; }
to
      inline value_type operator*() { return m_node; }
?

Granted, in general, you'd expect a reference from operator*(), but this is such
a rarely-used part of the API that I don't really feel too bad about breaking
with convention slightly to make the implementation easier.  But maybe you feel
differently.

I've not been able to come up with another way to do it elegantly.  The only
thing I've come up with so far is creating an independent std::list<Element>
that's a member of Path and whose members refer to the underlying
cairo_path_data_t pointers.  Then we could make use of the
std::list<Element>::iterator type and we'd also have a bunch of Element objects
that are already instantiated, so we could return references to them.  But this
seems like an unnecessary amount of overhead for this API.
Comment 9 Murray Cumming 2006-08-15 10:31:30 UTC
I think this needs to wait for a next version of cairomm's API, such as a
cairomm 1.1/1.2, so we can freeze the 1.0 API now.

I'd like cairomm to follow the GNOME release schedule.
Comment 10 Jonathon Jongsma 2006-08-15 10:35:35 UTC
(In reply to comment #9)
> I think this needs to wait for a next version of cairomm's API, such as a
> cairomm 1.1/1.2, so we can freeze the 1.0 API now.
> 
> I'd like cairomm to follow the GNOME release schedule.

That's fine.  This interface isn't quite ready yet anyway.  (By the way, we're
already at 1.1/1.2.  We bumped the version up to 1.1.10 for the last release to
indicate that we were wrapping the new cairo 1.1/1.2 API.  So the next one would
be 1.3/1.4 I guess)
Comment 11 chemtech 2013-03-15 14:19:05 UTC
jonner 
Do you still experience this issue with newer drivers ?
Please check the status of your issue.
Comment 12 GitLab Migration User 2018-08-25 13:23:07 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/cairo/cairomm/issues/2.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.