FreeType 生成不对称字形

FreeType producing asymmetric glyphs

所以我正在尝试在我的图形引擎中实现带有符号距离字段的字体渲染。

为此,我使用 FreeType 库生成所有字母的字形。具体来说,我正在尝试像这样加载单色位图:

FT_Load_Char(face, c, FT_LOAD_RENDER | FT_LOAD_TARGET_MONO)

然后我从字形缓冲区中提取所有位并将其放入我可以在屏幕上显示以用于测试目的的单色黑白纹理。

我提取位并将其放入字节数组的代码:

FT_Bitmap bm = face->glyph->bitmap;

FT_Bitmap mono;
FT_Bitmap_New(&mono);
//convert from 8 pixel per byte to 1 pixel per byte
FT_Bitmap_Convert(ft, &bm, &mono, 1);
//set each byte from 0/1 to 0/255
for (int y = 0; y < mono.rows; y++) {
    for (int x = 0; x < mono.width; x++) {
        mono.buffer[y * mono.width + x] *= 255;
    }
}

但是我的问题是,FreeType 生成的字形似乎是不对称的。

例如,这是使用字体 OpenSans-Regular 的字体像素大小为 64 的字母 M:

这是字母M,字体相同,像素大小为1024:

我已经尝试过使用多种字体、多种字体大小等,并且某些字形始终保持不对称。 另请注意,我手动读取纹理像素数据以验证 OpenGL 的纹理缩放或其他不会导致错误的内容。

关于为什么 FreeType 似乎会产生不对称字形的任何想法,或者谁能告诉我这在以后渲染文本时是否会成为问题?

编辑:我现在使用库函数提取位,所以错误一定是在 FreeType 的某个地方。

您在这里假设 OpenSans 是一种所有 glpyhs 都是对称的字体。事实并非如此,也不是 FreeType 错误。您可以随时向 freetype 列表发送电子邮件,但可能会得到相同的答案。

这不是不准确,因为字体设计师出于他选择的任何原因将 M 字形设计为非对称。很多时候,这样做是为了提高可读性。一点不对称会导致提示引擎以稍微不同的方式栅格化字形,这将更清晰或看起来更 'crisp'。下面放几张截图来证明是这样的。

首先,这是 Windows 10/Chrome 55 在浏览器中以网站允许我 select 允许的最小尺寸呈现字形的大幅放大屏幕截图。虽然乍一看确实是对称的,但事实并非如此。

其次,我下载了字体并在FontForge中打开。如果仔细观察,可以发现两侧内侧边缘的曲线实际上略有不同。我还花点时间查看了定义 M 底部中心的两个点。它们的位置是 (848, 0) 和 (985, 0)。这两个点之间的中点是 (916.5, 0),但是定义这部分字形顶部边缘的两个点位于 (920, 256) 和 (928, 256)。这是稍微向右移动。

如果您正在寻找对称或其他简单字体,请寻找适合程序员的字体或控制台字体。 Arial、Consolas、Courier New 等可能非常适合。