FreeType 如何计算预付款?

时间:2021-02-18 17:39:33

标签: c++ truetype freetype

我想弄清楚 FreeType 库是如何计算 FT_GlyphSlotRec_advance 变量的。根据此结构上方的注释块,此变量将与 horiAdvance 变量相同,进一步解释了 here,后者包含在 FT_Glyph_Metrics_ 结构中。

无论如何,以典型的Arial窄字体为例。它可以在 C:\Windows\Fonts\ARIALN.TTF 中找到。将其上传到任何基于 Web 的 TTF 文件编辑器(option 1option 2),或使用您自己的可以解释 TTF 文件的程序(fontforge 等),您可以看到“!”的 Advance字符明确定义为 467。

我正在运行以下代码,当我读取 FT_GlyphSlotRec_advance.x 值时,我得到的值为 1472。显然这与 467 不同。我是否误解了这代表的含义?还是我错误地使用了 FreeType 库?

我正在重新输入我用来从没有互联网的计算机上获取 1472 的代码,所以请原谅我的任何普通语法错误。

#include <string>
#include <ft2build.h>
#include FT_FREETYPE_H

using namespace std;

int main() {
  FT_Uint font_height = 100;
  FT_Library ft;
  FT_Face face;
  char* filepathname; // Defined through code that was excluded for the sake of simplifying this example

  FT_Init_FreeType(&ft);
  FT_New_Face(ft, filepathname, 0, &face);
  FT_Set_Pixel_Sizes(face, 0, font_height);
  
  FT_Uint glyph_idx = FT_Get_Char_Index(face, 33);
  FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER);

  FT_Pos advance_x = face->glyph->advance.x;

  return 0;
}

main() 末尾断开导致 Advance_x 为 1472。

1 个答案:

答案 0 :(得分:1)

如您在问题中链接的教程第 2 步页面所示,这些指标通常以 26.6 像素格式报告。您正在通过加载字体的方式修改它。您可以使用 FT_LOAD_NO_SCALE 来“[不] 缩放加载的轮廓字形,但将其保留在字体单位中。”

您的代码会以您要求的大小以 72 dpi 的默认屏幕分辨率生成字形的位图版本。您得到的 1472 是用于在位图中绘制字符的像素数 * 64。因此,在这种情况下,1472 / 64 = 23 像素,如果您在同一个位图中绘制多个字符,这将是您前进绘制光标/笔点的距离。

467 是 1/2048 向量单位。要使用 100 像素的 font_height 进行转换,则为:467/2048 * 100 像素,即 22.8 像素。舍入到 23 像素。乘以 64 得到 1472 1/64 像素。

如果您想看到它与像素值对齐,请将您的 font_height 设置为 2048,然后将生成的 face->glyph->advance.x (29888) 除以 64,得到 467。

以下脚本将为您提供您正在寻找的值:

#include <string>
#include <ft2build.h>
#include <stdio.h>
#include FT_FREETYPE_H

using namespace std;

int main() {
  FT_Library ft;
  FT_Face face;
  string filepathname = "./arialn.ttf";

  FT_Init_FreeType(&ft);
  FT_New_Face(ft, filepathname.c_str(), 0, &face);
  
  FT_UInt glyph_idx = FT_Get_Char_Index(face, '!');
  FT_Load_Glyph(face, glyph_idx, FT_LOAD_NO_SCALE);

  printf("width=%ld height=%ld\nhoriBearingX=%ld horiBearingY=%ld horiAdvance=%ld\n vertBearingX=%ld vertBearingY=%ld vertAdvance=%ld\n",face->glyph->metrics.width,face->glyph->metrics.height,face->glyph->metrics.horiBearingX,face->glyph->metrics.horiBearingY,face->glyph->metrics.horiAdvance,face->glyph->metrics.vertBearingX,face->glyph->metrics.vertBearingY,face->glyph->metrics.vertAdvance);
  FT_Pos advance_x = face->glyph->advance.x;
  printf("advance_x = %ld \n",advance_x);

  return 0;
}

输出:

width=183 height=1466
horiBearingX=148 horiBearingY=1466 horiAdvance=467
vertBearingX=-85 vertBearingY=228 vertAdvance=1922
advance_x = 467