繁体   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