2017-04-07 265 views
0

我繼承了一個代碼,其中作者使用FreeType和OpenGL打印一些文本(不一定是等寬字體)。如何在FreeType中獲取文本寬度?

我需要計算打印的文本寬度,以便我可以正確對齊它。

這是他寫的代碼:

freetype::font_data font; 
font.init(fontPath.c_str(), fontSize); 
freetype::print(font, x, y, "%s", str.c_str()); 

Here是FreeType的源與print功能。

我想不出任何辦法通過修改print函數來獲取文本的寬度,我試圖編輯字體的init功能(也提到文件)返回face->glyph->metrics.width但有一個例外,說face->glyph爲空。但我認爲我甚至不應該試圖編輯圖書館的來源。

由於我不知道如何獲得文本寬度,我正在考慮以某種方式打印文本,獲得打印內容的寬度以及打印內容的寬度。任何想法可能?

+0

從我記憶中,你走在正確的軌道上。你必須打印文本,你可以使用一個屏幕緩衝區。應該有辦法以像素爲單位獲取打印的寬度。 – Jay

回答

2

如果你只限於使用拉丁字符,這是一個簡單和骯髒的方式來做到這一點。

您可以通過字形迭代,加載每個字形,然後計算邊界框:

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; 

} 

,但如果你想這樣做更專業,我想你必須使用的HarfBuzz(或複雜的文本整形庫)。它是一種萬能的靈魂,一旦你編譯完成,你可以用它來繪製和測量拉丁字符串,也可以測量Unicode字符串。我強烈建議你使用這個。