2

我一直在用 FreeType 渲染文本。尤其是非 ascii 字符让我头疼。经过反复试验,我设法渲染了一些文本,但我的变音符号没有显示:

std::string text = "Hauptmenü";
for(std::string::iterator it = text.begin(); it != text.end(); ++it) {
    std::cout << *it;

    FT_Face face = loadFace(faceName);

    FT_Set_Pixel_Sizes(face, 0, fontSize);

    if(FT_Load_Char(face, *it, FT_LOAD_DEFAULT)) {
        std::cout << "Could not load character '" << character << "'" << std::endl;
    }

    FT_Get_Glyph(face->glyph, &glyph);
    FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);

    //render the glyphs to screen and so on
}

加载字体、获取字形等基本上可以工作,但没有渲染“ü”。这是我的输出的样子:

显示除“ü”以外的所有字符!

显示除“ü”以外的所有字符!

控制台输出

这最终出现在我的控制台中,所以我猜我对字符串的迭代一定有问题,因为“ü”被分成两个字符。我为最后两个字符获得的字形位图的宽度和高度均为 0。

我怎样才能解决这个问题?

4

2 回答 2

7

精简版

阅读: http ://www.joelonsoftware.com/articles/Unicode.html

使用这个: http: //www.pango.org/

长版

您似乎对文本表示和一般呈现有一些误解(您使用放弃软件“检查”文本输出显示它)。幸运的是,乔尔在描述问题方面做得相当不错:http: //www.joelonsoftware.com/articles/Unicode.html

FreeType 能够解析 True Type 文件,并渲染存储在文件中的字形。它不是一个成熟的文本渲染引擎。您使用的字体甚至可能没有呈现所需字符所需的字形,您可能需要组合不同的字形以产生所需的输出。

当然,您不会自己实现整个 Unicode 渲染逻辑,这是一项艰巨的任务。如果您只想将“文本”扔给它并渲染它,则必须使用更高级别的东西。至少是 HarfBuzz,或者其他的东西,比如 Pango 或 Qt。在SDL_Pango 库中可以看到如何使用 Pango+FreeType 的一个很好的例子。

于 2013-10-04T08:23:25.443 回答
0

您的问题是并非所有字符都可以用单个字节表示。大多数国际字符(如ü)需要两个(或更多)。您的字符串基本上是一个字符数组,不适合一个字节的字符将被解释为两个字符。

一种解决方案是使用 std::wstring ,它基本上是一个 wchar_t 数组。您的代码将变为:

std::wstring text = L"Hauptmenü";
for(std::wstring::iterator it = text.begin(); it != text.end(); ++it) {
    std::wcout << *it;

    FT_Face face = loadFace(faceName);

    FT_Set_Pixel_Sizes(face, 0, fontSize);

    if(FT_Load_Char(face, *it, FT_LOAD_DEFAULT)) {
        std::wcout << L"Could not load character '" << character << L"'" << std::endl;
    }

    FT_Get_Glyph(face->glyph, &glyph);
    FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);

    //render the glyphs to screen and so on
}

这还有很多, DanielKO 链接到的文章是一个很好的开始。

于 2020-09-10T06:54:51.777 回答