9

我正在尝试使用 freetype 2.6 库从一些 .ttf 字体中提取字距调整信息。

这就是我获取字距调整信息的方式(循环字符):

if( FT_HAS_KERNING(face->getFace()) && previous ){
    FT_Vector delta;
    FT_UInt glyph_index = FT_Get_Char_Index( face->getFace(), character );
    FT_UInt prev_index = FT_Get_Char_Index( face->getFace(), previous );
    FT_Get_Kerning( face->getFace(), prev_index, glyph_index,
                        FT_KERNING_DEFAULT, &delta );
    kerning = delta.x >> 6;
}

我尝试了一些不同字体的程序:“Times new roman.ttf”、“Tymes.ttf”、“minion.otf”。仅对于 Times new Roman 字体,字距调整信息已正确提取,我通过记录信息进行了检查。

问题是我不明白为什么其他 2 种字体的字距始终为 0(即 FT_HAS_KERNING 返回 false,并且 FT_GetKerning 无论如何都返回 0)。

我用 fontforge 检查了“VA”和“To”对的字距调整信息,它们就在那里!所以它们必须存储在 .ttf 中。然而,对于上面的代码,“VA”或“To”的字距始终为 0,否则 FT_HAS_KERNING 返回 false。

我在这里缺少任何自由类型选项或设置吗?任何形式的启蒙都值得赞赏..

编辑:我正在设置面部大小

FT_Set_Pixel_Sizes( face->getFace(), 0, size);

编辑:fontforge 中“tymes”字体的字距调整信息: 在此处输入图像描述

4

1 回答 1

7

Freetype 只能从字体kern表中检索字距调整值,而不是从更现代的实现中作为 OpenType 功能使用GPOS. 从文档中:

请注意,OpenType 字体 (OTF) 提供了两种不同的字距调整机制,分别使用 OTF 文件中的“kern”和“GPOS”表。较旧的字体只包含前者,而最近的字体只包含两个表格甚至“GPOS”数据。FreeType 仅支持通过(相当简单的)“kern”表进行字距调整。为了解释(高度复杂的)“GPOS”表中的字距调整数据,您需要一个更高级别的库,如ICUHarfBuzz,因为它可以依赖于上下文(也就是说,字距调整可能会根据文本字符串中的位置而有所不同,例如)。

您的 FreeType 代码适用于 Times New Roman(我的是“Monotype:Times New Roman Regular:Version 5.11 (Microsoft)”),因为它包含两个表:

tag 'GPOS'  checksum 5dfeb897  offset   778576  length    43506
tag 'kern'  checksum a677acd1  offset   734088  length     5220

但其他字体不包含该字体kern

GPOSkerning 比 plain 更受欢迎,kern因为它的表格可以链接到特定的脚本和语言,并且它提供了更好的控制。

仅包含一种类型的表格也有充分的理由——如果两者都存在,则由字体渲染器选择一个。例如, Microsoft 的 OpenType Fonts 建议如下:

OFF 规范允许 CFF OT 字体在紧缩表中表达它们的紧缩。许多 OFF 文本布局引擎都支持这一点。然而,Windows GDI 的 CFF OT 驱动程序在准备字距调整对以通过其对字距调整 API 报告时忽略 CFF OT 字体中的字距表。
当字体中同时存在紧排表和 GPOS 表时,并且请求关闭布局引擎将紧排应用到特定脚本和语言系统的文本运行: (a) 如果已解析的紧排特征查找的数量GPOS 表中的语言系统为零,则应应用紧排表,然后是请求的任何剩余 GPOS 功能。(b) 如果 GPOS 表中已解析语言系统中的紧排特征查找数不为零,则应以通常方式应用所有 GPOS 查找,包括紧排查找,并且忽略紧排表数据。

于 2015-08-04T11:42:21.193 回答