【问题标题】:How to get glyph unicode using freetype?如何使用freetype获取字形unicode?
【发布时间】:2020-06-16 22:37:08
【问题描述】:

我正在尝试使用 freetype 来枚举字体文件中的字形(名称和 unicode)。

为了获取名称,我使用的是 FT_Get_Glyph_Name。 但是我怎样才能得到字形 unicode 值呢?

我是字形和字体的新手。

【问题讨论】:

    标签: freetype


    【解决方案1】:

    人们会期望FT_CharMap 保存此信息:

    [...] 当前激活的charmap 可用face->charmap

    但不幸的是,它只定义了编码的种类(Unicode、MacRoman、Shift-JIS 等)。显然,查找代码的行为是在别处完成的——而.notdef 只是在该字符不可用时返回。

    查看我自己的一个报告“按名称”的基于 FreeType 的 OpenType 渲染器,在可能的情况下,我在初始化序列中发现了一些代码,它存储一个字形的名称(如果有的话),否则是 Unicode。但该代码是基于字形名称的存在。

    进一步思考:您可以测试每个可能的 Unicodecodepoint 并查看它是否返回 0 (.notdef) 或有效的字形索引。因此,为所有可能的字形初始化一个空表,并且仅在以下例程找到它时填写每个字符的 Unicode。

    对于适度现代的字体,您只需要检查 Unicode U+FFFF;对于像繁重的中文字体(对于 Heiti SC 最高为 U+2F9F4)或 Emoji(对于 Segoe UI Emoji 最高为 U+1FA95),您需要一个更大的数组。 (从字体中获取最大数量是一个完全不同的故事,唉。决定做什么取决于你想用它做什么。)

    printf ("num glyphs: %u\n", face->num_glyphs);
    for (code=1; code<=0xFFFF; code++)
    {
        glyph_index = FT_Get_Char_Index(face, code);
        /* 0 = .notdef */
        if (glyph_index)
        {
            printf ("%d -> %04X\n", glyph_index, code);
        }
    }
    

    这个简短的 C sn-p 打印出从字体字形索引到相应 Unicode 的转换表。请注意 (1) 并非字体中的所有字形都需要与它们关联的 Unicode。有些字体有大量的“额外”字形,用于 OpenType 替换(例如替代设计和自定义连字)或其他用途(例如前面提到的 Segoe UI 表情符号;它包含所有表情符号的颜色掩码)。并且 (2) 某些字形可能与多个 Unicode 字符相关联。例如,A 的字形设计既可以用作拉丁文大写字母 A,也可以用作希腊文大写字母 Alpha。

    【讨论】:

    • 有一个更好的way 可以从面部的选定charmap 中检索Unicode 代码点。
    【解决方案2】:

    Unicode 代码点在技术上并不与 TrueType/OpenType 字体中的字形一起存储。必须迭代字体中的字体cmap 表才能获得映射,这也可能是非Unicode 映射,并且可能存在指向同一字形的多个映射。好消息是,FreeType 在 API 中提供了迭代当前选定字符映射中的字形代码点的工具,这非常好documented。所以,用代码:

    // Ensure an unicode characater map is loaded
    FT_Select_Charmap(face, FT_ENCODING_UNICODE);
    
    FT_ULong charcode;
    FT_UInt gid;
    
    charcode = FT_Get_First_Char(face, &gid);
    while (gid != 0)
    {
        std::cout << std::format("Codepoint: {:x}, gid: {}", charcode, gid) << std::endl;
        charcode = FT_Get_Next_Char(face, charcode, &gid);
    }
    

    利用这些信息,您可以创建从字形到 Unicode 代码点的尽力而为的映射。

    【讨论】:

      【解决方案3】:

      并非字体中的所有字形都必须具有 Unicode 代码点。在 OpenType 文本显示中,Unicode 字符序列和字形序列之间存在 m:n 映射。如果您对 Unicode 代码点和字形之间的关系感兴趣,最有意义的事情是使用从 Unicode 代码点到字体“cmap”表中包含的默认字形的映射.

      有关更多背景信息,请参阅OpenType spec: Advanced Typographic Extensions - OpenType Layout

      至于字形名称,每个字形都可以有一个名称,无论它是否从“cmap”表中的代码点映射。字形名称包含在“post”表中。但并非所有字体都必须包含字形名称。例如,CJK 字体不太可能包含字形名称。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-09-15
        • 2012-04-16
        • 2018-03-04
        • 2015-05-22
        • 2013-04-19
        • 2016-10-11
        • 1970-01-01
        相关资源
        最近更新 更多