无法使用freetype获取某些特定.ttf字体的字距

时间:2015-08-03 08:02:29

标签: true-type-fonts freetype freetype2 kerning

我正在尝试使用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字体,正确提取字距调整信息,我通过记录信息来检查。

问题是我不明白为什么字距调整总是为0(即FT_HAS_KERNING返回false,而FT_GetKerning仍然为0返回0)其他2种字体。

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

我在这里缺少任何freetype选项或设置吗? 任何一种启蒙都受到赞赏..

编辑: 我用

设置了脸部大小
FT_Set_Pixel_Sizes( face->getFace(), 0, size);

编辑: 字典中“tymes”字体的字节信息: enter image description here

1 个答案:

答案 0 :(得分:5)

Freetype只能从字体kern表中检索字距调整值,而不能使用GPOS从更现代的实现中检索作为OpenType功能。来自documentation

  

请注意,OpenType字体(OTF)分别使用“kern”和“GPOS”表提供两种不同的字距调整机制,这些表是OTF文件的一部分。较旧的字体仅包含前者,而最近的字体仅包含表格或“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字体。

GPOS字距比普通kern更受欢迎,因为它的表可以链接到特定的脚本和语言,并提供更好的控制。

还有很好的理由只包含一种类型的表 - 如果两者都存在,则由字体渲染器选择一种。例如,Microsoft's Recommendations for OpenType Fonts声明如下:

  

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