Я пытаюсь использовать этот потрясающая версия freetype 2 с моей мультиплатформенной библиотекой. Я еще не тестировал его на Android, но я пытался скомпилировать и протестировать его под win32. Он прекрасно компилируется без ошибок, но всегда вылетает, когда библиотека пытается прочитать «данные» (что всегда плохой указатель) члена TT_CMap. Функция, в которой это происходит, зависит только от файла шрифта, то есть один шрифт — одно место. Я пробовал разные шрифты ttd от Windows, MacOS X и от Android, но это влияет только на положение, где произойдет сбой сегментации.
Например, если я попытаюсь получить индекс любого шрифта стандартного шрифта окна arial.ttf, он всегда будет падать здесь:
static FT_UInt tt_cmap4_char_map_binary( TT_CMap cmap, FT_UInt32* pcharcode, FT_Bool next )
{
[...]
p = cmap->data + 6;
num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
[...]
из-за cmap-> data неверный указатель.
Мой тестовый код выглядит так:
int error = 0;
// Initialize freetype library first
error = FT_Init_FreeType( &ft_lib );
if ( error ) {
ODF(("Unable to init freetype library! Error code is %d.\n", error));
return false;
}
// Load font file into the memory buffer
iMemBuff faceFileBuff;
if (igelLoadResource(iString("Data/arial.ttf"), faceFileBuff) != ROR_Success) {
ODF(("ERROR: Unable to open font file!\n"));
return false;
}
// Init font
error = FT_New_Memory_Face( ft_lib, (FT_Byte*)faceFileBuff.GetPtr(), faceFileBuff.GetSize(), 0, &ft_face );
if ( error == FT_Err_Unknown_File_Format ) {
ODF(("ERROR: the font file could be opened and read, but it appears that its font format is unsupported.\n"));
return false;
} else if ( error ) {
ODF(("ERROR: %d error code means that the font file could not be opened or read, or simply that it is broken...\n", error));
return false;
}
// Setup font metrics
error = FT_Set_Pixel_Sizes( ft_face, 0, 16 );
// error = FT_Set_Char_Size(ft_face, 0, 16*64, 300, 300 );
if ( error ) {
ODF(("ERROR: Unable to set char/pixel size! Error code %d.\n", error));
return false;
}sint32 ox = 0, oy = 0;
int error = 0;
FT_GlyphSlot slot = ft_face->glyph; // a small shortcut
for (uint32 cc=0; cc<text.StringSize(); ++cc) {
// Find the character 'a' index
int glyph_index = FT_Get_Char_Index( ft_face, text.CStr()[cc] );
// Load glyph
error = FT_Load_Glyph( ft_face, glyph_index, FT_LOAD_DEFAULT );
if ( error ) {
ODF(("ERROR: Unable to load face from the font! Error code %d.\n", error));
continue;
}
// Render the glyph
error = FT_Render_Glyph( ft_face->glyph, FT_RENDER_MODE_NORMAL );
if ( error ) {
ODF(("ERROR: Unable to render glyph! Error code %d.\n", error));
continue;
}
// Draw the glyph to our target surface
ComposeGlyph(image, &slot->bitmap, ox + slot->bitmap_left, oy + slot->bitmap_top);
ox += slot->advance.x >> 6;
}
И происходит сбой, когда я вызываю FT_Get_Char_Index с любым персонажем …
Любая идея?
В моем случае проблема в том, что cmap-> data становится плохим указателем, когда я освобождаю блок памяти шрифтов, переданный в FT_New_Memory_Face (). cmap-> data сохраняет силу, пока я сохраняю блок памяти.
Хотя это, похоже, не ваш случай, просто хочу внести свой вклад.
Других решений пока нет …