【问题标题】:FreeType how to render special chars like ü ä ö?FreeType 如何渲染像 ü ä ö 这样的特殊字符?
【发布时间】:2013-10-04 07:52:30
【问题描述】:

我一直在用 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。

我该如何解决这个问题?

【问题讨论】:

    标签: c++ opengl freetype


    【解决方案1】:

    短版

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

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

    加长版

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

    FreeType 能够解析 True Type 文件,并渲染存储在文件中的字形。它不是一个成熟的文本渲染引擎。您使用的字体可能甚至没有呈现所需字符所需的字形,您可能会通过need to combine different glyphs 产生所需的输出。

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

    【讨论】:

    • 不确定为什么您认为需要 Pango。 ü 可以表示为单个 Unicode 代码点,FreeType 可以在没有帮助的情况下呈现 Unicode 代码点,只要它们存在于字体中。
    • @MSalters:假设我不使用 Pango,我将如何正确迭代每个代码点并将其提供给 FT_Load_Char?
    • @LarsEbert : std::wstring ?
    • 谢谢,这就是我需要的。我正在慢慢地从 php 开发迁移到 c++,并且很难适应。
    【解决方案2】:

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

    一种解决方案是使用 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
    }
    

    这还有很多,the article DanielKO 链接到是一个非常好的开始。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-13
      • 2012-05-20
      • 1970-01-01
      • 2016-07-21
      • 2020-10-17
      • 1970-01-01
      • 2017-04-28
      相关资源
      最近更新 更多