簡體   English   中英

使用翻轉的正交渲染FreeType文本,字形的頂部和基線之間的差異

[英]Render FreeType text with flipped ortho, difference between top and baseline of glyph

我正在開發一個項目,我在其中實現一個FreeType渲染對象來繪制文本,其中渲染環境是使用正交投影矩陣指定的:

glm::ortho(0, Width, Height, 0);

這確保坐標類似於標准GUI系統,其中(0,0)是窗口的左上部分而不是左下角。

然而,當使用FreeType進行渲染時,事情變得困難,因為FreeType的操作原點位於字形的左下角(減去下降部分)。 我的問題類似於https://stackoverflow.com/questions/25353472/render-freetype-gl-text-with-flipped-projection但尚未提供答案,他的解決方案不符合我的意願(使用的庫也是略有不同,我假設他正在使用包裝器)。

所以我將我的文字渲染如下:

renderText("Testing 123 if text performs sufficiently", 0.0f, 0.0f, 1.0f, 1.0f);

其中renderText函數包含:

renderText(const GLchar *text, GLfloat x, GLfloat y, GLfloat sx, GLfloat sy)
{
    [...]
    GLfloat xpos = x + glyph->bitmap_left * sx; 
    GLfloat ypos = y - glyph->bitmap_top * sy; 
    GLfloat w = glyph->bitmap.width * sx;
    GLfloat h = glyph->bitmap.rows * sy;
    // Update VBO
    GLfloat vertices[4][4] = {
        { xpos,     ypos,       0, 0 },
        { xpos + w, ypos,       1, 0 },
        { xpos,     ypos + h,   0, 1 },
        { xpos + w, ypos + h,   1, 1 }
    };
    [...]
}

如果我像這樣渲染它,它將渲染y坐標為0以下的文本,因此除非我向y坐標添加偏移量,否則它將不可見。 所以看一下FreeType的字形指標:

FreeType中的字形指標

我想將y位置偏移一個等於字形圖像的原點和頂部之間的差值的正數量,這樣它總能整齊地將文本呈現在我給定的位置。 查看圖像我認為這是yMax值,所以我在更新VBO之前將以下語句添加到代碼中:

ypos += (glyph->face->bbox.yMax >> 6) * sy; 

當我加載字體大小為24的FreeType字形時,似乎解決了這個問題,但是當我嘗試使用不同的字體大小時,它無法正常工作,因為此圖像顯示:

字體大小差異

正如你所看到的,它顯然不能像我想象的那樣工作。 如果我遺漏了一些東西,我一直在搜索FreeType的文檔,但我找不到它。 我使用錯誤的指標(使用Ascender不起作用)?

我想將y位置偏移一個等於字形圖像的原點和頂部之間的差值的正數量,這樣它總能整齊地將文本呈現在我給定的位置。 查看圖像我認為這是yMax值,所以我在更新VBO之前將以下語句添加到代碼中:

    ypos += (glyph->face->bbox.yMax >> 6) * sy;

實際上, yMax並不是你感興趣的。你可以使用yMax - yMin來找到你的字形的高度,但這確實是它的好處。

從FreeType 2 API文檔中, FT_GlyphSlotRec::bitmap_top是:

位圖的頂部方位以整數像素表示。 請記住,這是從基線到最頂部字形掃描線的距離,向上y坐標為

再看看你在問題中包含的圖像,即有效bearingY 你的問題是你不應該從你的ypos中減去這個值。 你確實需要這個值,我將在下面解釋,但你絕對不想減去它。

如果從ypos的計算中刪除bitmap_top ,則會得到以下內容:

錯誤對齊

這顯然是不正確的,因為它忽略了字符串中每個字符之間的上升差異。

現在,仔細查看以下正確對齊的圖表:

在上圖中,我已經說明了你的字符串最頂部的紅線,最底部的綠色和灰色的所有字形的基線。

正如您所看到的,大寫字母'T'具有最大的上升,並且這種泛化適用於大多數字體。 在紅線正下方,我已經說明了資本'T'和當前字母之間的上升差異為黃色區域。 這是您必須計算以正確對齊字符串的重要數量。

可以如下計算上面正確對齊的圖中的黃色區域:

    Chars['T'].bitmap_top - glyph->bitmap_top

如果你停止從ypos減去glyph->bitmap_top並添加上面的值,你應該得到與正確對齊的圖相同的結果。


對於獎勵積分,如果您想將文本與屏幕底部對齊,則概念非常相似,只有您對最大下降的角色(通​​常是小寫的'g' )與當前角色之間的差異感興趣。 這是灰色基線和綠線之間的距離,可以在您的字形度量圖中表示為height - bearingY

您應該能夠使用以下方法計算下降:

(glyph->metrics.height >> 6) - glyph->bitmap_top // bitmap_top is in integer coords

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM