[cairo] UserFontFace vs FtFontFace management (cairomm)

Jonathon Jongsma jonathon at quotidian.org
Tue Dec 2 20:44:26 PST 2008

Behdad Esfahbod wrote:
> What you describe is very close to how it is perceived, but I think I was
> careful enough to not make that mistake.  The two methods that have
> interdependencies are text_to_glyphs and unicode_to_glyphs.  However, the docs
> for text_to_glyphs give you a way to essentially say "unimplemented":
> [snip tens of lines of docs]
>  *
>  * The callback is optional.  If @num_glyphs is negative upon
>  * the callback returning, the unicode_to_glyph callback
>  * is tried.  See #cairo_user_scaled_font_unicode_to_glyph_func_t.
>  *
> So all you need to do is to make sure your default implementation sets
> num_glyphs to -1.
> Being able to implement user fonts in, say, Python is quite a nice feature and
> I expect one to simply subclass cairo.UserFontFace for that indeed.  At some
> point I'll update the binding chapter and clarify this, but so far my plans to
> tackle that part of the cairo tree have failed miserably.
> Cheers,
> behdad

OK, I took a closer look at this again, and it seems there will still be some problems in 
implementing these as virtual functions with default implementations.  For example, in the 
documentation for cairo_user_scaled_font_init_func_t, it says the following:

  * The callback is optional.  If not set, default font extents as described
  * in the previous paragraph will be used.

But if we implement these callbacks as virtual functions with default implementations, 
this callback will *never* not be set, so I don't see a way to get the fallback 'default 
font extents' behavior.

Now, regarding the unicode_to_glyph documentation you quoted above, the fact that you 
overload the 'num_glyphs' parameter with a special negative number sentinel makes it 
somewhat cumbersome to wrap cleanly in languages that have better support for arrays.  In 
C, in order to pass an array as an argument, you need to pass the array pointer and the 
length, but array types in many other languages have the concept of length built into the 
type itself.  So if we were to wrap this function naturally (i.e. passing the glyphs as an 
array), it is not really possible to set num_glyphs to a negative value.  For instance, my 
current text_to_glyphs function signature in cairomm is:
   cairo_status_t text_to_glyphs(const RefPtr<ScaledFont>& scaled_font,
                                 const std::string& utf8,
                                 std::vector<Glyph>& glyphs,
                                 std::vector<TextCluster>& clusters,
                                 TextClusterFlags& cluster_flags);

Perhaps there's a better way to design that interface, but as you can see the idea was 
simply to pass the glyphs as a vector (array).  So with this interface the user has no way 
to return a negative value for num_glyphs -- std::vector::size() maps to num_glyphs, and 
the size of an array is always non-negative.  So in order to provide a default 
implementation for this virtual function that returned a -1 for num_glyphs, It seems that 
I would either have to revert to using C-style arrays, or I would need to add an 
additional sentinal argument to the cairomm interface (e.g. 'bool& 
call_unicode_to_glyphs_instead' :).  Neither of these options seem especially satisfying 
to me.


More information about the cairo mailing list