[cairo] User font take 2

Kristian Høgsberg krh at bitplanet.net
Wed May 3 18:09:16 PDT 2006


Here's an update on the user font feature that I've been working on. 
Since the last update, I've made poppler use user fonts for rendering
type3 fonts, and I've incorporated some of Behdads suggestion from his
reply.  Patch against cairo head is attached or browse the code in the
user-font branch in my git archive.

The proposed API addition is:

typedef struct _cairo_user_font_backend {
    void          *(*scaled_font_create)  (cairo_scaled_font_t       
                                           const cairo_matrix_t      
                                           const cairo_matrix_t       *ctm,
                                           const cairo_font_options_t *options,
                                           cairo_font_extents_t       *metrics);
    void           (*scaled_font_destroy) (void                 *closure);

    unsigned long  (*ucs4_to_index)       (void                 *closure,
                                           unsigned long         ucs4);

    cairo_status_t (*get_glyph_metrics)   (void                 *closure,
                                           unsigned long         index,
                                           cairo_font_options_t *font_options,
                                           cairo_text_extents_t *metrics);

    cairo_status_t (*render_glyph)        (void                 *closure,
                                           unsigned long         index,
                                           cairo_font_options_t *font_options,
                                           cairo_t              *cr);
} cairo_user_font_backend_t;

cairo_public cairo_font_face_t *
cairo_user_font_face_create (const cairo_user_font_backend_t *backend);

and there's an example of using the API here:


Changes since last time:

- instead of passing in a bunch of function pointers the API takes a
struct of function pointers.  There's no precedent for this in the
cairo API, but I've chosen to go with 'backend' as the suffix for the
struct name as used internally in cairo.
- I added callbacks for scaled font creation and destruction. The
scaled_font_create callback returns a void pointer which is used for
the 'closure' argument passed to all other callbacks and eventually
destroyed in the scaled_font_destroy callback.
- the render_glyph callback now takes a cairo_t to render to.  This
context is initialized to font space, with the origin at the glyph
- I dropped the get_glyph_path callback; instead the plan is to call
render_glyph with a meta_surface or maybe just a custom surface to get
the glyph paths when possible.

I didn't change the api to use text_to_glyphs instead of
ucs4_to_index.  I think, that even if we add a text_to_glyphs callback
we should keep the simpler ucs4_to_index in place, so we don't force
users of the user font  api to do utf8 to ucs4 conversion that's part
of the text_to_glyphs functionality.

Also, I didn't implement the bypass-cache flag that Behdad suggests,
as I feel it goes against the motivation for this feature, and I'm
sceptical that it's really useful. The use case I'm concerned about is
the poppler type3 support, of course, but more generally, I see this
feature as a way to pass user provided glyphs through to underlying
surface backends glyph mechanishm (ps/pdf type3 fonts, svg fonts,
bitmap glyph cache) in order to handle them more efficiently. The
bypass-cache flag defeats this optimization and the randomization
effects described can be acheived with other means just as

Still missing is ARGB glyph support - we need to know what kind of
content the glyph surface will hold before creating it and calling the
render_glyph callback.  We could piggy back the glyph content type
information on the get_glyph_metrics callback, which should be
straight forward.  However, it *is* information that the user font
implementation have to provide, we can't deduce this from a meta
surface recording of the glyph.

Other than the issue mentioned above, I believe the API is sufficient,
if a bit more compact that Behdad suggested.  At this point, however,
I'm not comfortable suggestion this for 1.2.  It's too much new API
this late in the cycle and it needs some more soak time and one or two
other users before I want to push for it's inclusion.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: user-font.patch
Type: application/octet-stream
Size: 14578 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20060503/4912951c/user-font-0001.obj

More information about the cairo mailing list