【问题标题】:How is FreeType calculating advance?FreeType 是如何计算提前的?
【发布时间】:2021-02-18 17:39:33
【问题描述】:

我试图弄清楚 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。

【问题讨论】:

  • "1472 is not the same as 467" 是没有任何单位信息的无意义比较。
  • @molbdnilo 我希望我知道要告诉你关于单位的内容。处理字体指标对我来说是新的。我们在谈论 em 大小吗?还有什么?我知道face-&gt;glyph-&gt;advance.x 是 26.6 小数像素格式,这意味着 1 个单位等于 1/64 像素。
  • 您正在使用 FT_Set_Pixel_Sizes 更改比例 - 所以您的 advance.x 取决于您的 font_height。
  • @MarkusSchumann 这很有帮助,但我似乎仍然无法让 Advance.x 与 ARIALN.ttf 中嵌入的 467 Advance 相匹配。我必须在这个函数中提供一些值,并且 font_height 为 32 会产生最接近的 Advance.x 448,但仍然不是 467。我也玩过 FT_Set_Char_Size(),利用零宽度和 32 * 64 高度,产生类似的结果。
  • 你从哪里得到 467?

标签: c++ truetype freetype


【解决方案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 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    • 2018-03-29
    • 2022-07-15
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    相关资源
    最近更新 更多