Я реализую рендеринг шрифтов в приложении OpenGL с использованием библиотеки FreeType2.
Моя проблема в том, что инициализация более одного FT_Face
объекты вылетает программа. Я пытался иметь один экземпляр FT_Library
и звонит FT_Init_FreeType()
для каждого нового шрифта. Я также пытался иметь отдельные случаи FT_Library
для каждого шрифта.
Обе инициализации работают, но потом я получаю утверждение от malloc.c
когда я использую new
оператор в следующий раз, независимо от того, где, буквально на следующей строке кода.
Вот метод создания объекта Font, в котором инициализируется lib FreeType2:
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 *) &((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.
ОБНОВИТЬ:
Объявление класса шрифта, версия с экземпляром библиотеки 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_New_Face
Вы уверены, что font->_face
был новым? Итак, вам нужен новый FT_Face
если font->_face
нулевой.
Заметка: Нет необходимости инициировать 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_Face
) из FT_New_Face
должен быть экземпляром. FT_New_Face
не выделяйте память для FT_Face
,
Других решений пока нет …