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.
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
.