[cairo] UserFontFace vs FtFontFace management (cairomm)
behdad at behdad.org
Wed Dec 3 11:49:21 PST 2008
Jonathon Jongsma wrote:
> 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.
Sure, it documents what happens if it's not set. Your job is to ensure that
your default implementation causes the same behavior.
Note that it says "default font extents as described in the previous
paragraph". That previous paragraph says:
* [...] @extents is preset to
* hold a value of 1.0 for ascent, height, and max_x_advance, and 0.0 for
* descent and max_y_advance members.
So all your fallback needs to do is to not touch extents.
> 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.
I'm not sure whether you are being lazy or the docs are so horribly bad :).
> 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.
I agree that it's clumsy. It happened to offset for the fact that there is no
public CAIRO_STATUS_UNIMPLEMENTED. The documentation is only for the C
version. Your binding layer is free to do otherwise.
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.
You can make the method raise an exception for example.
> 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.
The C interface is now written in stone. What we can do is to add a special
cairo_status_t value for this case that will be interpreted as UNIMPLEMENTED
only when used in this context. That's possible if you don't find any other
More information about the cairo