Reputation: 983
I inherited a code where author prints some text (not necessarily in monospace font) using FreeType and OpenGL.
I need to calculate printed text width so I can align it properly.
Here is the code he wrote:
freetype::font_data font;
font.init(fontPath.c_str(), fontSize);
freetype::print(font, x, y, "%s", str.c_str());
Here is the FreeType source with print
function.
I couldn't think of any way to get the text width by modifying print
function and I tried editing font's init
function (also in mentioned file) to return face->glyph->metrics.width
but there was an exception saying that face->glyph
is null. But I don't think I should even be trying to edit sources of libraries.
Since I have no clue how to get the text width I'm considering somehow printing the text, getting the width of what was printed and printing something over it. Any ideas on that maybe?
Upvotes: 0
Views: 4356
Reputation: 309
if you are confined to using Latin characters, here is a simple and dirty way to do it.
you can iterate over glyphs, load each glyph and then calculate the bounding box:
int xmx, xmn, ymx, ymn;
xmn = ymn = INT_MAX;
xmx = ymx = INT_MIN;
FT_GlyphSlot slot = face->glyph; /* a small shortcut */
int pen_x, pen_y, n;
... initialize library ...
... create face object ...
... set character size ...
pen_x = x;
pen_y = y;
for ( n = 0; n < num_chars; n++ )
{
FT_UInt glyph_index;
/* retrieve glyph index from character code */
glyph_index = FT_Get_Char_Index( face, text[n] );
/* load glyph image into the slot (erase previous one) */
error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
if ( error )
continue; /* ignore errors */
/* convert to an anti-aliased bitmap */
error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL );
if ( error )
continue;
/* now, draw to our target surface */
my_draw_bitmap( &slot->bitmap,
pen_x + slot->bitmap_left,
pen_y - slot->bitmap_top );
if (pen_x < xmn) xmn = pen_x;
if (pen_y < ymn) ymn = pen_y;
/* increment pen position */
pen_x += slot->advance.x >> 6;
pen_y += slot->advance.y >> 6; /* not useful for now */
if (pen_x > xmx) xmx = pen_x;
if (pen_y > ymx) ymx = pen_y;
}
but if you want to do it more professionally, I think you must use harfbuzz (or a complex text shaping library). it is a one-size-fits-all soultion, meaning once you get it compiled, you can use it to draw and measure not only Latin strings but also Unicode ones. I strongly recommend you use this one.
Upvotes: 4