Domanda

I'm implementing fonts rendering in OpenGL app using FreeType2 library. My problem is that initializing more then one FT_Face objects crashes the program. I tried having single instance of FT_Library and calling FT_Init_FreeType() for each new font. I also tried havind separate instances of FT_Library for each font. Both initializations work, but then I get assertion from malloc.c when I use new operator next time no matter where, literaly on the next line of code.

Here is the Font object creation method where FreeType2 lib gets initialized:

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);
}

This peace of code works just fine if I call it once. If I call it for the second time and then somwhere later in another part of the program I create object via new, application crashes.

What is wrong here? There should be some good way for loading several fonts...

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

UPDATE:

Font class declaration, version with ft library instance per class:

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() method basicly uses _face to peek required chars and render them.

È stato utile?

Soluzione

Before call FT_New_Face, are you sure the font->_face was new? So, you need new a FT_Face if font->_face is NULL.

Note: It is not necessary to init a FT_Library for each Font instance. You can make the Font::_ft to be static.

Finally, code should be:

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;

At last, you need uninitialize/release all memory about FreeType2 when call destructor.

Note: The fourth variable (FT_Face) of FT_New_Face must be instance. The FT_New_Face don't allocate the memory for FT_Face.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top