[cairo] UserFontFace vs FtFontFace management (cairomm)

Jonathon Jongsma jonathon at quotidian.org
Wed Dec 3 21:29:42 PST 2008


Ian Britten wrote:
> If something awkward/tricky needs to be done, I'd (personally) rather
> deal with it in one spot, rather than many.  As such, I'd be willing
> to put up with some warts when _deriving_ a custom class (Once),
> rather than each and every time I need to actually _use_ the derived
> class.
> 
> Thus, I'd be open to adding silly "isFooOverridden()=0" methods,
> or anything else(*) that would give you the information you need,
> if it meant keeping the general usage of the class clean and simple.
> (*) Maybe a 'getFooMethod()' that returns a member pointer, with
>   the default returns NULL?  Dunno - Just another hack thought...
> 
> At the moment, I'm trying to figure out where/how to manage the
> extra attributes I'm going to need, and am not looking forward to
> helper structures, manual memory management, void pointers, etc.
> Having a derived "MyUserFont", with members, copy constructor,
> destructor, etc, would be well worth almost any other cost I had
> to pay when deriving the class.

So, I think that we can redesign the UserFontFace interface to let you do this without 
*too* much ugliness, but I'm now realizing that this does not solve your initial issue at 
all -- regardless of whether the callbacks are done by stored functor objects or class 
virtual methods, they both require that the wrapper object stay alive as long as the 
callbacks are needed.  It is the nature of wrapper libraries that the wrapper objects are 
created and destroyed as needed.  For example, consider the following case:

...
{
   Cairo::RefPtr<Cairo::ToyFontFace> face = Cairo::ToyFontFace::create(...);
   cr->set_font_face(face);
} // scope for demonstration purposes
cr->show_text("hello, world");

Notice that in this example, the C++ wrapper 'face' will be destroyed by the smart pointer 
when it reaches the closing brace, but the underlying C type (cairo_font_face_t) will live 
on because cairo_set_font_face() takes a reference internally.  Then later if we call 
cr->get_font_face(), we'll create a brand new C++ wrapper object for the very same 
underlying C object.  This is usually fine because the C++ wrapper is just a very thin 
layer that keeps no state of its own.  However, as soon as the C object needs something 
from the C++ wrapper object (for example, it needs to call one of its virtual functions), 
then all of a sudden it matters that the C object and the C++ wrapper have different 
lifetimes.  I've been racking my brain trying to figure out a way to make this work, but 
I'm afraid I don't have any good ideas so far.  Any other binding authors have any insight 
on this?

> 
> Anyways, that's just my $0.02 - Use it as you best see fit  :)
> I'll probably have to proceed with the current (1.7.0) stuff for
> now, but wouldn't have any objection if you change+improve things
> in a future version.

-- 
jonner


More information about the cairo mailing list