我尝试在OpenGL和FreeType2中渲染文本,我不知道在渲染字体时如何获得每行之间的空间(以像素为单位)。当我解析文本时,我希望能够做类似
的事情const char *text = "some text\n here";
for(char *p = text; *p; p++)
{
if(*p == '\n')
{
y -= newLineDistance;
continue;
}
...//render text here
}
起初我用过
newLineDistance = face->glyph->metrics.vertAdvance >> 6;
但它不适用于某些字体,因为文档还说它对非垂直字体(中文等)不可靠。
答案 0 :(得分:9)
没有必要计算行间距,因为FreeType已经提供了它。自己计算它也可能会产生错误的结果,因为它是艺术家定义的。例如,小写字母的最低部分' g'可以延伸到下面一行大写字母的最高部分以下。
来自文档: http://www.freetype.org/freetype2/docs/tutorial/step2.html
高度
此字段表示使用此字体书写文本时的默认行间距(即基线到基线距离)。请注意,它通常大于ascender和descender之和作为绝对值。使用此距离时,也无法保证在后续基线之上或之下没有字形延伸 - 将其视为字体设计者认为合适的值。
如何使用它:
// initialise freetype
FT_Library ft;
FT_Init_FreeType(&ft);
// load a font
FT_Face face;
FT_New_Face(ft, "path_to_font.ttf", 0, &face);
// set the font size, e.g. 48 pixels
FT_Set_Pixel_Sizes(face, 0, 48);
// get the default line spacing, note that it is measured in 64ths of a pixel
int line_spacing = face->height;
// get the scaled line spacing (for 48px), also measured in 64ths of a pixel
int scaled_line_spacing = face->size->metrics.height;
答案 1 :(得分:1)
你是什么意思非垂直字体?字体不是真正的水平或垂直,但是当您打印一些文本时,可以垂直或水平排列字形。您会发现,对于大多数字体,字形存储两组属性(水平和垂直前进),以便您可以根据自己的选择水平或垂直排列文本。
如果要水平绘制文本,则不会使用字形的前进,前进是用于文本字符串中字符之间的间距。对于线之间的间距,您真正想要的是知道最大上升和下降(基线上方/下方的距离),以便您的线不重叠。
实际上,您可以在不知道字符串中的任何字符的情况下计算行之间所需的间距。如果您知道字体中具有最大上升和下降的字符,则可以执行此操作。在罗马字体中,具有最大上升的字符通常为T
,而具有最大下降的字符为g
。我对中文并不熟悉,所以我不能告诉你一般的经验法则,但我确信有一个。
在上图中,字母g
的上升由bearingY
衡量,下降可以计算为bearingY - height
。线之间的最小间距将是线中每个字形的最大上升和下降之和。请记住,最好将此概括为整个字体,并保持间距一致,而不是为您打印的每个字符串实际计算它(您的线条会根据哪些字符取消垂直位置载)。