[Cairo] Text APIs round 2

Owen Taylor otaylor at redhat.com
Fri Aug 15 08:47:49 PDT 2003

On Thu, 2003-08-14 at 21:20, Keith Packard wrote:
> Around 16 o'clock on Aug 14, Owen Taylor wrote:
> > Is the lack of a 'scale_font' or a size in select_font intentional?
> Hmm.  It seems like having scale_font/transform_font functions separate 
> from select_font would avoid needing those varients of the os-dependent
> functions.  If you can't change the scale of an existing font, then the 
> scale should be supplied when the font is created, otherwise it should be 
> supplied in a separate call.  I'd vote for making fonts unscalable; it 
> makes using bitmap fonts much more practical and avoids issues with 
> partially specified 'fonts' doing weird things when you start drawing.

The way postscript handles this is that fonts start off with a default
size of 1 unit... sort of useless, but at least gives *some* meaning
to the situation.

> > I think you might want to reduce the set of out parameters here
> > with a judicious structure or two. E.g. the XGlyphInfo
> > structure of XftTextExtents, or pango_*_extents() pair
> > of &ink_rect, &logical_rect.
> Ok, I think that will be cleaner.  However, I think we should have a
> cairo_text_dx function that returns the X (and Y?) escapements for "dumb" 
> applications that just want to do spacing.

How about _width()?

> > For Pango, my plan for vertical writing is that dy == 0 by
> > definition, but I guess the convention for Postscript is
> > that dx == 0 for vertical writing.
> How does this work?  Does vertical writing perform no automatic layout?

That's not really a meaningful question for Pango, since Pango doesn't
have a a "draw string" call, just various "lay out this text" calls.

But the basic idea is that the end effect is that if you draw vertical
text without setting the appropriate 90 degree or 270 degree rotation
matrix, then you get output that you have to turn 90 degrees or
270 degrees to read. (90 degrees versus 270 degrees depends on whether
you are setting Chinese or Mongolian.)

For characters that stay upright, this will involve Pango setting 
a 270 degree transform when loading the font, which, in the normal
case will cancel with the 90 degree transform that the app sets.

Pango will still be handling lots of details for the application;
(http://www.w3.org/TR/css3-text/), but keeping the y axis always 
aligned with the direction of line advance means that that we
won't have to fill code with all sorts of 

 "if vertical do this, if horizontal, do that"

> > I tend to agree with others that the inclusion of the font here
> > is vaguely annoying. It's not necessary for efficiency, and
> > not really necessary for correctness. 
> It is an efficient win -- I can generate a single compositing call for
> all of the glyphs.  For Render that's a single protocol request while for 
> core X, it's a single get/put image.

I don't think the extra protocol requests matters at the frequency
that font changes; we should be able to eliminate virtually all
get/put round trips with Cairo.

> Not having this varient eliminates this relatively modest performance 
> improvement
> > Pango uses the position-but-no-font variant of the Xft API.
> That's a bit surprising.  Note that there is no affect in the wire protocol for 
> using the font-per-glyph API; Xft merges sequences of glyphs using the 
> same font into a single chunk.  We found it much easier in Mozilla to let 
> Xft manage that task than to do it in the browser, but perhaps complex 
> layout means you're already doing quite a bit of work every time the font 
> shifts.

Well, the Pango API's basic drawing call is "draw this string of glyphs
in this font"...

> > What's the relationship between the size in the FcPattern
> > and the scale parameter?
> I'm not really sure; we can either have it override any size found in the 
> FcPattern or ammend it.  I'd vote for the former.

I'd agree. Maybe deviating from postscript and calling it 'size'
rather than scale would make things clearer.

> > I'm not sure that the treatment of sizing here is coherent. 
> > A FT_Face is tied to the pixel grid, So, I don't really see
> > how we obtain one independent of a cairo_context_t.
> Hmm.  Looks like cairo_font_t is going to be per-cairo_context_t; the 
> alternative is to bind them very late in the process which seems like a 
> pain (because you'll have to associate them before you can do
> anything) and not very useful.
> > I'd definitely have the feeling that scale/transform should
> > be in the generic API. Since they are presumably relative
> > to the current transform not to the pixel grid, I'm not sure
> > it's even *possible* to implement them at the font-system
> > specific layer.
> Can you 'rescale' a font?  What does that mean?  What happens if you never 
> scale a font?  If we can rescale fonts, then the binding between a font 
> and the underlying os-dependent structure is going to change whenever this 
> happens, so any previous fetches of that object will be invalidated.

Well, the alternative is that we invalidate cairo_font_t objects
when the transform of the context changes, and that to me, seems
like an unnecessary hazard to the API. I'd rather have hazards
for the people using cairo_ft_font_get_face() rather than hazards
for people using cairo_select_font().

> > _destroy() as well. The toy API is going to need a generic
> > way to destroy a cairo_font_t, so it might as well be part
> > of the public API.
> If we eliminate the os-dependent datatypes, then _destroy() can be generic.

I don't think that's a necessary condition; cairo_font_destroy()
can be virtualized. But if this is the only place there is 
'derivation' in the API, using a single typedef probably in the
public APIs probably makes sense.

Calling cairo_ft_font_get_face() on a non-FT cairo_font_t should
get a warning/abort rather than an error return. There is
no reason to give error indications on programming bugs, but
it's nice to tell the programmer what they did wrong.

> > > Should we support bitmap fonts at all?
> > I don't think there is any particular harm API-wise 
> I'm concerned about the effect of needing to lazily bind names to fonts 
> that this will cause.  If we support only outline fonts, then the scaling/
> transformation really is independent of the font selection which realy 
> does change how the internals would work.  This is visible because we can 
> return the underlyin object.  Also, what does 'cairo_font_scale' mean when 
> you hand an FT_Face to cairo which has only a single fixed size in it?

We already accept non-linearity in font scaling for outline fonts,
though it's typically pretty subtle. Bitmap fonts just are a really
excessive form of this. Bitmap fonts only really are useful
when you are working in "widget mode" - you have 1 unit == 1 pixel
and don't set any transforms. I think it's OK if they produce 
weird/garbaged output when used in other modes.


More information about the cairo mailing list