[cairo] Rendering line fonts

Ian Britten britten at caris.com
Thu Nov 27 06:21:26 PST 2008

Behdad Esfahbod wrote:

> Fair enough, but then I don't see why you are abusing freetype here.  The main
> reason one would want to use freetype for their custom font format is to get
> the rasterization done by freetype.  You don't seem to use that at all.

I think we're looking at things from slightly different perspectives.

Although rendering is important, we do much, much more with text than
just rendering it (Fancy curved layouts, Unicode/RTL, HTML-like markup,
editing, etc).  As such, having a single unified way of working with
all types of fonts is a huge benefit for us.  Previously, we tried to
manage TT fonts one way, and legacy fonts another way, and it resulted
in lots of extra, error-prone code.  Now, we just use a thin C++
wrapper around the FT_Face, and everything is simpler and consistent.

The only concession we had to make was to drop the closing point when
drawing stroke fonts, which seemed to be a small price to pay for the
benefit we got.  For everything else, we're using the normal FT
rendering mechanism (FT_Outline_Render(), FT_Outline_Decompose()).
For most of our outputs, we're just rendering to image-like surfaces,
like on-screen, or image files, and whether the 'outline' is an open
or closed path is largely irrelevant.

However, with this new Cairo/PDF option, I didn't want to simply
output rasterized images to the PDF but instead the actual text.  As
such, for this optional Cairo backend, I'm trying to circumvent our
normal rendering path (so we don't rasterize the text), and pass the
actual FT_Face to Cairo.  I fear that this has resulted in my
descriptions sounding strange/confusing, and if so, I apologize.  In
any case, it's mostly my problem, and should have no bearing on Cairo.

> Yes.  This is the pseudocode of how you should handle your FT_Face:
>   cairo_face = cairo_ft_font_face_create_for_ft_face (ft_face);
>   if (ft_face is my custom format and a stroke font)
>     cairo_face = my_stroke_font_face_create (cairo_face, thickness);
> Where my_stroke_font_face_create() creates a cairo user-font.  You then use
> the cairo_face normally.
>> - Finally, render it as described by Behdad in his message:
>>        cairo_glyph_path (cr, &cairo_glyph, 1);
>>        cairo_stroke (cr);
> No this is what your user font's render function does.  You really should go
> study cairo/test/user-font-proxy.c before replying.

[ I had, but still didn't 'get it' ... :P ]

Ok, many thanks for this higher-level description!  I see what's
going on now.  Also, I hadn't seen, nor appreciated, the difference
between cairo_glyph_path() vs cairo_show_glyphs().  The
cairo_glyph_path() is the key nugget that I think will solve my
problem.  Also, I think it will also help be with some future stuff
I'll need to support, like text "halos" [ See the text on Google Maps ]

Now that I see what's going on, this begs the question:  Do I actually
*need* to use any of the user font stuff?  Why can't I just:
     cairo_face = cairo_ft_font_face_create_for_ft_face (ft_face);
     cairo_set_font_face(cr, cairo_face);
     cairo_set_font_matrix(cr, matrix);
     if (my stroke font)
             // Set whatever else...  Cap/Join/etc...
             cairo_glyph_path (cr, &cairo_glyph, 1);
             cairo_stroke (cr);
             cairo_show_glyphs(cr, &cairo_glyph, 1);

Initial hacking/playing shows positive results :) but I'm left
wondering what I might be missing/omitting?  It sure seems
simpler... [ Keeping in mind the framework I'm fitting into ]

As always, many thanks for your help (And patience)!

More information about the cairo mailing list