[cairo] First draft of font changes

Owen Taylor otaylor at redhat.com
Tue Jan 18 10:35:37 PST 2005


On Tue, 2005-01-18 at 10:01 -0800, Keith Packard wrote:
> Around 12 o'clock on Jan 18, Owen Taylor wrote:
> 
> >  1. cairo_ft_lock_face(), like XftLockFace doesn't protect against
> >     locking different fonts pointing to the same underlying file.
> 
> I like explicitly exposing locking shared among multiple threaded cairo 
> users. It does mean that the locking granularity is quite large, and that 
> application bugs can cause unlocked access to shared objects, but the 
> alternative seems to be inscrutible locking semantics with concommitment 
> deadlock joy.
> 
> This raises the larger issue about where else in the cairo API we should 
> provide shared locking mechanisms.  Should we provide a cairo_lock/
> cairo_unlock which libraries and applications can use to ensure 
> single-thread access to cairo functions?

In general, the model I think we've been discussing a threading model
where:

 - Any two Cairo objects can be used from different threads; Cairo
   does necessary locking internally to make this work
 
 - Access to the *same* Cairo object from different threads needs
   locking at the app level.

The font handling screws this up because of the internal cache,
though only when you drop down and access FT_Face objects. But we
shouldn't have the same problem in most other places.

> > 2. Pango uses face->generic.data in a FT_Face for storing a pointer
> >    to its own data.
> 
> It sounds like we need cairo_font_t private storage then.  Should this be 
> keyed in any way so that multiple private objects can be depended from the 
> font?

Actually, Pango needs it for the FT_Face, not for the cairo_font_t ...
what it uses for is storing parsed OpenType tables that are scale
independent, expensive to compute, and large. That could be done by:

 a) Exposing cairo_unscaled_font_t to the public interface and
    putting private storage on that
 b) Exposing an API that takes a FT_Face and multiplexes from
    face->generic.data

> >  3. The functions to create a cairo_font_t currently take a composite
> >     scale (font matrix * ctm).
> 
> I'll let you decide who holds the separate object containing the font 
> matrix; it doesn't matter that much within the cairo space.

Right now the font_matrix is held in the PangoFont... 

> >  4. Should cairo_font_glyph_extents() take only a single glyph
> >     rather than a string of glyphs,
> 
> Yes, this is a necessary change given that the font object has no notion 
> of user space.  It has the advantage of moving the complex piece of the 
> metrics computation up to shared code instead of being almost duplicated 
> in several font backends.

Well, cairo_font_glyph_extents() has I have it now takes the 
font_matrix_t and does the computations you had in cairo_gstate. I
certainly agree that the complicated logic should be moved out
of the backends. The question is whether to split the things so
cairo_font_glyph_extents() handles the translation-to-user-space
and _cairo_gstate_glyph_extents() the "extents of multiple glyphs".

My instinct is no.

[...]

> >  6. cairo_ft_font_create_for_ft_face() takes a FT_Face object that
> >     must be kept alive as long as Cairo is using the font.
> 
> This is equivalent to the FILE object in PS/PDF/PNG surfaces and should be 
> solved in the same way -- the cairo_font_t can be 'finished' which 
> releases the connection with the FT_Face without destroying the 
> cairo_font_t object itself; further usage of that cairo_font_t is an error.
> 
> destroy notifiers considered harmful.

Probably need to split this issue off to separate discussion. While a
"dead" state for cairo_ft_font is certainly possible, I can't agree with
the distaste for destroy notifiers. They simplify so much code.

> >  7. Should we get rid of cairo_font_scale_t and use cairo_matrix_t
> >     always?
> 
> yes.  Assertions in the public API that the translate components are zero 
> would catch potential bugs.

That's just painful. It's useful to be able to do things like multiply
the font matrix by the ctm and get a scale. Having to zero the
translation doesn't seem add anything.

> > 8. Right now, the the image glyph cache goes from
> 
> Issue 3) provides this uniqified object.  Would you create per-unique 
> glyph caches?  Or continue using the global glyph cache?  The global cache 
> has the advantage of being a bit easier to eject objects from, although 
> I'm not sure it weighs larger glyphs more when selecting which to eject.

Hmm, as I see it, we already have the potentially uniqified object ..
cairo_font_t. Issue 3) takes it away, though we have the ability
to reintroduce it.

It definitely doesn't weight larger glyphs when selecting which to
eject... that would take some complex logic.

> >  9. The code doesn't currently assert if you unlock more times than
> >     you lock.
> 
> Asserts are good.  Should we have warning assertions for things like this?

The GLib g_return_if_fail() setup for entry checks tends to give more
stability to GTK+ apps, at the expense of allowing lazy programmers
to not treat broken assertions same-as-segfault.

> > 11. cairo_ft_font_create() doesn't actually try to open the font,
> 
> It should open the font, and might be able to now that we expose only 
> pixel-size specific font objects through the public API.

Hmm, I guess assuming that a font will be used shortly after it
is created is a pretty good assumption. (Pango creates PangoFont
up front and depends on it being lazy somewhere along the line, but it
creates cairo_font_t lazily at the moment anyways.)

> We'll have to make the cairo_t code not load a font on create though.

Already done with my patch

> > 12. When using the toy API, a font matrix from fonts.conf (the 
> >     default does artificial oblique) will be ignored.
> 
> 3), 8) and 12) all push for an internal pixel-size specific font object 
> with a separate fm/ctm cairo_font_t object.  It seems like we have 
> a strong push in this direction here.

I'm not sure I see them as all pushing in the same direction, but a
3-level split is a certainly possible solution to all three.

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/20050118/8da197df/attachment.pgp


More information about the cairo mailing list