[cairo] UserFontFace vs FtFontFace management (cairomm)

Jonathon Jongsma jonathon at quotidian.org
Mon Dec 8 07:11:56 PST 2008


Murray Cumming wrote:
>>> It is cairo that calls destroy on the attached user data when the ref 
>>> count is 0.
>>> Then, I destroy the Ada create object(s).
>>> If I'm correct, there is no cycle here.
>>> I think this is applicable to C++: Replace "Ada handle" by "C++ smart 
>>> pointer" and "Ada object" by "C++ wrapper".
>>
>> Yes, thank you.  This does seem like the proper way to do things, and I spent this weekend 
>> redesigning things to work this way.  With those changes, things work just as you would 
>> expect them to (e.g. Ian's issue with needing to keep a reference to the UserFontFace 
>> object no longer exists).  However, I have not pushed this out, because the changes are 
>> quite invasive, and it would mean that we'd essentially be breaking the API/ABI of 
>> cairomm, which is obviously a big deal for projects using cairomm.  So I'm still thinking 
>> about the proper way to proceed...
> 
> I'd like to see that patch, though I hope it's not necessary.
> 
> I guess that you are using a separate refcount and a single cairo
> reference, much like this attempt to make Glib::RefPtr more generically
> useful:
> http://bugzilla.gnome.org/show_bug.cgi?id=104332
> 

Actually, the concept is much simpler -- RefPtr no longer has any reference count. 
There's basically two parts to the change.

RefPtr:
RefPtr<T> would no longer have any direct role in deleting the C++ wrapper object. It only 
calls T::reference() on copying (which should result in cairo_*_reference() being called), 
and T::unreference() on destruction (which should result in a call to cairo_*_destroy()).

Wrapped Objects:
In order for the previous RefPtr changes to work, the wrapper classes must be changed 
slightly.  When a wrapper object is constructed, it must install itself in the user_data 
of the underlying object.  Then when the C object's reference count reaches zero, the 
registered user_data destroy function will be called, which will result in the wrapper 
object being deleted.  This allows the wrapper function to live on after our last RefPtr 
has died if there is an internal reference held on the object somewhere.
-- 
jonner


More information about the cairo mailing list