简体   繁体   中英

How to get text width in FreeType?

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM