[cairo] Implementation notes on font rework

Owen Taylor otaylor at redhat.com
Fri Mar 18 14:11:51 PST 2005


API Changes
===========

/* We introduce a new virtualized object, cairo_font_name_t */

struct cairo_font_name_backend {
   cairo_scaled_font_t (*create_scaled_font) (void              *name,
                                              cairo_matrix_t 
*font_matrix,
                                              cairo_matrix_t    *ctm);
   cairo_scaled_font_t (*destroy)            (void              *name);
}

/* Given a font_name_t, we can make a scaled_font_t. Do we care about
  * the fact it might return a reference to an existing scaled_font?
  * I dont' think so since it's an immutable object.
  */
cairo_scaled_font_t *cairo_scaled_font_create (cairo_font_name_t *name,
                                                cairo_matrix_t 
*font_matrix,
                                                cairo_matrix_t    *ctm);

/* We can create font names for the toy API. Should be this be
  * create_simple() or somthing?
  */
cairo_font_name_t *cairo_font_name_create (const char           *family,
                                            cairo_font_slant_t    slant,
                                            cairo_font_weight_t   weight);

/* cairo_set_font (cairo_t *cr, cairo_font_t *font) is replaced
  * with set_font_name()
  */
void
cairo_set_font_name (cairo_t *cr, cairo_font_name_t *font);

/* cairo_font_extents() is renamed to cairo_font_extents() and
  * loses it's font_matrix argument, since we now store that
  * in the cairo_scaled_font_t.
  */
cairo_status_t
cairo_scaled_font_extents (cairo_scaled_font_t  *scaled,
                            cairo_font_extents_t *extents);

/* Same for cairo_font_glyph_extents */
void
cairo_scaled_font_glyph_extents (cairo_scaled_font_t   *font,
                                  cairo_glyph_t         *glyphs,
                                  int                    num_glyphs,
                                  cairo_text_extents_t  *extents);

/* The backends now have cairo_font_name_t constructors
  * rather than cairo_font_t constructors. (No scale argument)
  */

/* Should this one be for_pattern()? it's not obviously privileged */
cairo_font_name_t *
cairo_ft_font_name_create (FcPattern *pattern);

cairo_font_name_t *
cairo_ft_font_name_create_for_ft_face (FT_Face face,
                                        int     load_flags);

cairo_font_t *
cairo_win32_font_name_create_for_logfontw (LOGFONTW *logfont);


Structures
==========

struct cairo_win32_font_name {
      cairo_font_name_t base;
      LOGFONTW logfont;
};

struct cairo_win32_scaled_font {
      cairo_scaled_font_t base;
      LOGFONTW logfont;
      HFONT    font;
      [...]
};

struct cairo_ft_scaled_font {
      cairo_scaled_font_t base;
      cairo_ft_unscaled_font_t *unscaled
};

struct cairo_ft_unscaled_font {
      cairo_ft_font_name_t *name;
      FT_Face face;
      [...]
};

struct cairo_ft_font_name {
      cairo_font_name_t base;
      union {
        FT_Face *face
        struct { char *filename; int index; } file;
      } u;
      FT_Load_Flags load_flags;
}

Caches
======

Global cache:

      cairo_font_name_t/matrix/ctm => cairo_scaled_font_t

FreeType backend font name cache:

      filename/index/load_flags => cairo_ft_font_name_t

Toy API font name cache:

      family/slant/weight => cairo_font_name_t

Open questions
===============

  - In the above, I've named things cairo_font_name_t and
    cairo_scaled_font_t to correspond to the terminology
    in my previous mail. These aren't awful names, but they
    aren't great names either. cairo_font_name_t is in
    particular a bit strange.

    Other possibilities:

      cairo_font_name_t   => cairo_face_t
      cairo_scaled_font_t => cairo_font_t

    [ Rename cairo_select_font() to select_face ? ]

      cairo_font_name_t   => cairo_font_t
      cairo_scaled_font_t => cairo_scaled_font_t

    Other possibilities?

  - Using a global cairo_font_name_t/matrix/ctm =>
    cairo_scaled_font_t cache could conceivably not be right
    for some font backends? The weight of a cairo_scaled_font_t
    could differ considerably between backends ... and thus the
    number we want to cache.



More information about the cairo mailing list