【问题标题】:FreeType2 multiple facesFreeType2 多面
【发布时间】:2014-02-02 23:00:15
【问题描述】:

我正在使用 FreeType2 库在 OpenGL 应用程序中实现字体渲染。 我的问题是初始化多个 FT_Face 对象会使程序崩溃。我尝试使用FT_Library 的单个实例并为每种新字体调用FT_Init_FreeType()。我还尝试为每种字体设置单独的 FT_Library 实例。 两种初始化都有效,但是当我下次使用new 运算符时,无论在哪里,我都会从malloc.c 得到断言,字面上是下一行代码。

这里是 FreeType2 lib 初始化的 Font 对象创建方法:

Font::Font* create(const char* path, unsigned int size) {
  Font* font = new Font();

  FT_Init_FreeType(&(font->_ft));

  if(FT_New_Face(font->_ft, path, 0, font->_face)) {
    std::cerr << "Font: Could not load font from file " << path << "." << std::endl;
    return NULL;
  }

  FT_Set_Pixel_Sizes(*(font->_face), 0, size);
}

如果我调用一次,这种和平的代码就可以正常工作。如果我第二次调用它,然后稍后在程序的另一部分调用它,我通过new 创建对象,应用程序崩溃。

这里有什么问题?应该有一些加载几种字体的好方法......

断言消息:malloc.c:2365: sysmalloc: Assertion (old_top == (((mbinptr) (((char *) &amp;((av)-&gt;bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) &amp;&amp; old_size == 0) || ((unsigned long) (old_size) &gt;= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) &amp; ~((2 * (sizeof(size_t))) - 1))) &amp;&amp; ((old_top)-&gt;size &amp; 0x1) &amp;&amp; ((unsigned long)old_end &amp; pagemask) == 0)' failed.

更新:

字体类声明,每个类带有 ft 库实例的版本:

class Font
{
  public:
    static Font* create(const char* font, unsigned int size);
    void renderText(const wchar_t* text, float x, float y, float sx, float sy);

  private:
    Font();
    ~Font();

    FT_Library _ft;
    FT_Face* _face;
};

renderText() 方法基本上使用 _face 来查看所需的字符并渲染它们。

【问题讨论】:

  • 程序中有多个线程吗?你能告诉我们更多关于你的字体类的信息吗?
  • 只有一个线程。字体类描述会在一分钟内作为帖子的更新提供。
  • 字体构造函数和析构函数是什么?你为什么写FT_Face* _faceFT_New_Face(font-&gt;_ft, path, 0, font-&gt;_face)而不是FT_Face _faceFT_New_Face(font-&gt;_ft, path, 0, &amp;font-&gt;_face)

标签: c++ opengl freetype2


【解决方案1】:

在致电FT_New_Face 之前,您确定font-&gt;_face 是新的吗?因此,如果 font-&gt;_face 为 NULL,则需要新的 FT_Face

注意:不必为每个 Font 实例初始化 FT_Library。您可以将Font::_ft 设为静态。

最后,代码应该是:

class Font
{
public:
    static FT_Library      _ft;
    static Font* create(const char* path, unsigned int size)
    {
        Font* font = new Font();

        if (Font::_ft == NULL)
            if (FT_Init_FreeType(&Font::_ft))
                return NULL;

        if (font->_face == NULL)
            font->_face = new FT_Face;
        if (FT_New_Face(font->_ft, path, 0, font->_face)) {
            std::cerr << "Font: Could not load font from file " << path << "." << std::endl;
            return NULL;
        }

        FT_Set_Pixel_Sizes(*(font->_face), 0, size);
        return font;
    }

private:
    // Set the member - _face to NULL when call constructor
    Font() : _face(NULL) {}
    ~Font() { /* release the memory */ }
    FT_Face*        _face;
};

// Set the static member - _ft to NULL
FT_Library Font::_ft = NULL;

最后,你需要在调用析构函数时取消初始化/释放所有关于 FreeType2 的内存。

注意FT_New_Face 的第四个变量(FT_Face)必须是实例。 FT_New_Face 不为FT_Face 分配内存。

【讨论】:

  • 对我来说这看起来是个不错的实现。它可能不止一次调用 Ft_Init_FreeType 导致问题。除了 Alex 的解决方案之外,您还可以考虑使用工厂模式来确保对于每种字体/大小组合您只实例化一个对象。
  • 对不起,应该是享元模式。
  • 我终于让它工作了。当我将 _face 变成变量而不是指针时,问题就消失了。我无法想象它会出现什么问题。无论如何,感谢您的建议,拥有 FT_Library 的单个实例听起来很合乎逻辑。如果您对 FT_Face 作为指针的奇怪行为有解释,我会很高兴将您的答案标记为已接受。否则我会违反 SO 的规则 :)
  • 太好了,我会尽力做到最好的。但我说'所以,如果font-&gt;_face 为NULL,你需要新的FT_Face。',这意味着FT_Face 必须是FT_New_Face 中的实例。对不起,我的英语不好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多