[cairo] Font rendering options

Owen Taylor otaylor at redhat.com
Fri Jul 8 08:22:39 PDT 2005


On Thu, 2005-07-07 at 17:00 -0700, Keith Packard wrote:
> On Thu, 2005-07-07 at 18:57 -0400, Owen Taylor wrote:
> 
> > So, what would the API look like? The simplest thing to do would
> > be to make cairo_render_options_t a bitfield
> 
> When I did the same thinking for fontconfig (which has all of the same
> issues; fonts are selected without regard to the target surface and
> rendering options carried through this API), I used a name/values
> mechanism which seems more general and extensible than a bitfield. Is
> there some reason to prefer the fixed datatype over an extensible
> mechanism?

While FcPattern undeniably has a lot of power and flexibility, and in
fact, as you note, solves most of the issues I listed below, I'm not
a huge fan of the approach. There are various issues:

 - It doesn't language bind well. It's easy enough to bind it at the
   level of:

    pattern.addBoolean ("antialias", true);

   It's a lot harder (impossible) to bind it at the level of:

    pattern.antialias = true;

 - It doesn't document well. Our standard documentation tools pick
   up only the "meta-api", not the real API, which is the particular
   set of keys and their types nad allowed values.

 - Performance can be a concern. Pango performance design has largely
   been an exercise in figuring out out how to bypass fontconfig
   on the critical code paths. 

To exaggerate, one might say that the FcPattern approach has most of
the advantages and disadvantages of representing the font options with
a string.

Adding a reasonably complex key-value pair API to use just for one small
targeted place in the API also seems somewhat excessive.

Alternatives other than the complex bitfield:

 - An opaque structure

    cairo_font_options_t *cairo_font_options_create (void);
    cairo_font_options_t *cairo_font_options_copy (options);

    void                  cairo_font_options_destroy (options);
    void                  cairo_font_options_set_antialias (options,
                                                            antialias);
    cairo_antialias_t     cairo_font_options_get_antialias (options);

 - XGCValues style:

    typedef  struct {
       cairo_antialias_t antialias;
       [...]
    } cairo_font_options_t;


   void cairo_scaled_font_create (font_face, &ctm, &font_matrix,
                                  &options,
                                  CAIRO_FONT_OPTION_ANTIALIAS);
    
 - XSizeHints style

    typedef struct {
        cairo_font_options_mask_t mask;
        cairo_antialias_t antialias;
        [...]
    } cairo_font_options_t;

   void cairo_scaled_font_create (font_face, &ctm, &font_matrix,
                                  &options);

One advantage of the opaque object is that it binds very directly
into other languages. The disadvantage is a little clunkiness from
C, and some performance hit from mallocing tiny structures.
(The structure can be dealt with non-opaquely inside cairo, saving
some of that hit.)

> It handles all of the 'default' mechanisms, and permits non-enumerated
> values if we need them at some point.

[...]

> >  - It's easy to implement for both the X11 and Win32 font backends
> >  - It satisfies the needs of the toy API
> >  - It satisfies the needs of Pango
> >  - It's fundamentally a whole lot simpler than anything else I've 
> >    come up with
> > 
> > Bad things about this proposed API:
> > 
> >  - It puts some stuff into the generic cairo API which is not 
> >    very generic: the hint style options, for example, are something
> >    that is pretty unique to the fontconfig/FreeType stack.
> 
> Using general purpose name/value pairs allows each surface type to
> define new rendering options here instead of having to specify all of
> the possible rendering options right away.
> 
> >  - It doesn't allow for surface and font backends to interact in
> >    new ways without extending the enumeration
> > 
> >  - The use of a bitfield means that we can't extend the approach
> >    to rendering options that aren't boolean or enum-valued.
> > 
> >  - The use of a bitfield isn't language binding friendly (though we 
> >    could encourage people to bind it as an object with setters
> >    and getters for the different subfields)

The alternate approaches sketched above deal with the enum-valued and
language-binding issues. They don't really do anything for the question
of private options or backend-specific options, though until we 
add the ability to implement backends outside of cairo, these aren't
huge concerns.

> > Open questions:
> > 
> >  - How should render options from a FcPattern interact with the 
> >    options from the bitfeld?
> 
> What Fontconfig expects is for the application to place all of the
> rendering options into the FcPattern; those are then run through the
> match/edit steps which allows the user to modify the final rendering
> options.
> 
> We could do the same by having a function that constructed a
> cairo_render_options_t from an FcPattern and let the application run
> FontConfig until it hits the cairo interface at which point it converts
> to a cairo_render_options_t.
> 
> >  - Should we in fact have something like 
> >    cairo_set_font_render_options() in the toy API? Disabling
> >    metrics and outline hinting is something people will frequently
> >    want to do, especially with cairo_text_path().
> 
> This would be a cairo_scaled_font_t operation? I don't like that as we
> currently have immutable cairo_scaled_font_t objects. Alternatively, we
> could have cairo_render_options_t associated with the cairo_font_face_t
> which are applied to new cairo_scaled_font_t objects as they are
> created.

No, I meant as a cairo_t operation, so a new piece of the gstate ... in
parallel to the font_face and the font matrix. The problem with putting
it in the font face is that I'd also like to keep font faces immutable;
so you'd need cairo_select_font_face_with_options() or something,
which is ugly 

> >  - Naming specifics - cairo_render_options_t is a bit too 
> >    generic, but cairo_font_render_options_t is too long.
> 
> Could be cairo_font_options_t; I don't think that's too misleading.

Sounds good to me for a name.

Regards,
							Owen

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://lists.freedesktop.org/archives/cairo/attachments/20050708/6eb96f8e/attachment.pgp


More information about the cairo mailing list