Sammi De Guzman
Sammi De Guzman

Reputation: 567

FreeType: sizing fonts based on cap height?

I am rendering text, and I need the font to have the cap height to a certain number of pixels. For example, in the sign below, I need to have the words SPEED and LIMIT to be the same height, in this case 45 px, so I set the font size to 45 (which I now understand wasn't such a good idea) and get bounding boxes (in red) different from what I should have had.

So I create the font object,

Text *t = (Text *)e;
cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0);
cairo_t *cr = cairo_create(s);
cairo_font_face_t *font = cairo_ft_font_face_create_for_ft_face(fonts[t->series], 0);
cairo_set_font_face(cr, font);

Set the font size to 45,

cairo_set_font_size(cr, 1.5 * t->size);

Then calculate the extents of the bounding box, which doesn't line up with the correct size of the text.

cairo_text_extents_t ext;
cairo_text_extents(cr, t->data, &ext);
t->geom->height = ext.height; // t->size;
t->geom->width = ext.width;
t->lsb = ext.x_bearing;
cairo_font_face_destroy(font);
cairo_destroy(cr);
cairo_surface_destroy(s);

I'm guessing I have to use FT_Set_Pixel_Sizes or something, but I don't exactly know how to use that.

EDIT: Is there a way to set the cap height using Cairo? If so, I'd rather use that.

Upvotes: 0

Views: 916

Answers (1)

Sammi De Guzman
Sammi De Guzman

Reputation: 567

Using @Jongware's comment, I added a scale field which calculates the scaling factor for this particular piece of text (it should be consistent for a certain cap height).

cairo_text_extents_t ext, xext;
cairo_text_extents(cr, t->data, &ext);
cairo_text_extents(cr, "X", &xext);
t->scale = t->size / xext.height;
t->geom->height = t->size;
t->geom->width = ext.width * t->scale;
t->lsb = ext.x_bearing * t->scale;

It works perfectly now.

Upvotes: 2

Related Questions