Мой проект пытается загрузить шрифт для рендеринга из zip-файла. Я использую LibZip для доступа к zip-архиву, и процедура, которую я использую, отлично работает для всей графики, которую я визуализирую. Однако использование того же процесса для загрузки шрифта ttf в конечном итоге вызывает segfault, когда я пытаюсь визуализировать текст с помощью функций TTF_RenderText SDL_ttf. Я проверил эту причину, заменив код загрузки на TTF_Open и успешно загрузил его, в то время как загрузка из zip с использованием моего кода заканчивается segfault. Вот код, который я использую для загрузки файла из zip-архива:
TTF_Font* m_load_font(const char* filename, int fontsize) {
zip_stat_t filestat;
uint64_t filetotal;
SDL_RWops* rwop = SDL_AllocRW();
//Check to see if the data stream got allocated
if ( rwop == NULL ) {
u_error(std::cerr, CC_ERROR_SDL, "SDL_AllocRW");
SDL_FreeRW(rwop);
return nullptr;
}
//Check to see if the resource zip is open
if ( cc_zip_res == NULL ) {
std::cerr << "Font Load Error: Zip File Not Loaded" << std::endl;
SDL_FreeRW(rwop);
return nullptr;
}
//Open the file
zip_file_t* file = zip_fopen(cc_zip_res, filename, 0);
if (file == NULL) {
u_error(std::cerr, CC_ERROR_ZIP, "zip_fopen");
zip_fclose(file);
SDL_FreeRW(rwop);
return nullptr;
}
//Read the file
if(zip_stat(cc_zip_res, filename, 0, &filestat) == -1) {
u_error(std::cerr, CC_ERROR_ZIP, "zip_stat");
zip_fclose(file);
SDL_FreeRW(rwop);
return nullptr;
}
//Write data to a data holding array
char* rwbuffer = new char[filestat.size];
rwop = SDL_RWFromMem(rwbuffer, filestat.size);
while(filetotal < filestat.size) {
char buffer[256];
int64_t length;
//read the file into the buffer
length = zip_fread(file, buffer, 256);
if (length == -1) {
u_error(std::cerr, CC_ERROR_ZIP, "zip_fread");
zip_fclose(file);
SDL_FreeRW(rwop);
delete[] rwbuffer;
return nullptr;
}
//write the buffer into the rwop stream
if ( (size_t)length != SDL_RWwrite(rwop, buffer, 1, (size_t)length) ) {
u_error(std::cerr, CC_ERROR_SDL, "SDL_RWwrite");
zip_fclose(file);
SDL_FreeRW(rwop);
delete[] rwbuffer;
return nullptr;
}
//Increment the count so that the loop ends
filetotal += length;
}
zip_fclose(file);
//Return the seek pointer of the RWop to the beginning so that the file can be read
SDL_RWseek(rwop,0,RW_SEEK_SET);
//Load the font from the rwop
TTF_Font* temp = TTF_OpenFontRW(rwop, 0, fontsize);
SDL_FreeRW(rwop);
delete[] rwbuffer;
if (temp == NULL) {
u_error(std::cerr, CC_ERROR_TTF, "TTF_OpenFontRw");
}
return temp;
}
И вот код, который я использую, с TTF_RenderText:
bool CC_Texture::load_from_font(TTF_Font* font, std::string* text, SDL_Color color,
SDL_Renderer* ren) {
if (font == NULL) {
std::cerr << "Font is Null in CC_Texture::load_from_font" << std::endl;
return false;
}
//The wrap length is an estimate, will figure out the exact
SDL_Surface* surf = TTF_RenderText_Blended_Wrapped(font, text->c_str(), color, 600);
if (surf == NULL) {
u_error(std::cerr, CC_ERROR_TTF, "TTF_RenderText_Blended_Wrapped");
return false;
}
texture = std::shared_ptr<SDL_Texture>(SDL_CreateTextureFromSurface(ren, surf),
SDL_DestroyTexture);
if (texture.get() == NULL) {
u_error(std::cerr, CC_ERROR_SDL, "SDL_CreateTextureFromSurface");
return false;
}
return true;
}
EDIT: я также должен сказать, что Я использовал отладчик для сброса содержимого rwbuffer после того, как он загрузил, и это был действительный файл шрифта, поэтому не похоже, что чтение zip является проблемой.