Fix some memory leaks in sceFont.

Which were highlighted quite well by tests.
This commit is contained in:
Unknown W. Brackets 2014-03-30 12:55:40 -07:00
parent f55c81f096
commit 917af7b571

View file

@ -258,8 +258,23 @@ public:
LoadedFont() : font_(NULL) {
}
LoadedFont(Font *font, u32 fontLibID, u32 handle)
: fontLibID_(fontLibID), font_(font), handle_(handle), open_(true) {}
LoadedFont(Font *font, FontOpenMode mode, u32 fontLibID, u32 handle)
: fontLibID_(fontLibID), font_(font), handle_(handle), open_(true), mode_(mode) {}
~LoadedFont() {
switch (mode_) {
case FONT_OPEN_USERBUFFER:
case FONT_OPEN_USERFILE_FULL:
case FONT_OPEN_USERFILE_HANDLERS:
// For these types, it's our responsibility to delete.
delete font_;
font_ = NULL;
break;
default:
// Otherwise, it's an internal font, we keep those.
break;
}
}
const Font *GetFont() const { return font_; }
const PGF *GetPGF() const { return font_->GetPGF(); }
@ -278,7 +293,7 @@ public:
}
void DoState(PointerWrap &p) {
auto s = p.Section("LoadedFont", 1, 2);
auto s = p.Section("LoadedFont", 1, 3);
if (!s)
return;
@ -304,12 +319,18 @@ public:
} else {
open_ = fontLibID_ != (u32)-1;
}
if (s >= 3) {
p.Do(mode_);
} else {
mode_ = FONT_OPEN_INTERNAL_FULL;
}
}
private:
u32 fontLibID_;
Font *font_;
u32 handle_;
FontOpenMode mode_;
bool open_;
DISALLOW_COPY_AND_ASSIGN(LoadedFont);
};
@ -468,6 +489,7 @@ public:
return fonts_[index];
}
// For FONT_OPEN_USER* modes, the font will automatically be freed.
LoadedFont *OpenFont(Font *font, FontOpenMode mode, int &error) {
// TODO: Do something with mode, possibly save it where the PSP does in the struct.
// Maybe needed in Font, though? Handlers seem... difficult to emulate.
@ -488,8 +510,15 @@ public:
error = ERROR_FONT_INVALID_FONT_DATA;
return 0;
}
LoadedFont *loadedFont = new LoadedFont(font, GetListID(), fonts_[freeFontIndex]);
LoadedFont *loadedFont = new LoadedFont(font, mode, GetListID(), fonts_[freeFontIndex]);
isfontopen_[freeFontIndex] = 1;
auto prevFont = fontMap.find(loadedFont->Handle());
if (prevFont != fontMap.end()) {
// Before replacing it and forgetting about it, let's free it.
delete prevFont->second;
}
fontMap[loadedFont->Handle()] = loadedFont;
return loadedFont;
}
@ -679,6 +708,7 @@ void __FontShutdown() {
FontLib *fontLib = iter->second->GetFontLib();
if (fontLib)
fontLib->CloseFont(iter->second);
delete iter->second;
}
fontMap.clear();
for (auto iter = fontLibList.begin(); iter != fontLibList.end(); iter++) {
@ -770,7 +800,6 @@ u32 sceFontOpen(u32 libHandle, u32 index, u32 mode, u32 errorCodePtr) {
FontOpenMode openMode = mode == 0 ? FONT_OPEN_INTERNAL_STINGY : FONT_OPEN_INTERNAL_FULL;
LoadedFont *font = fontLib->OpenFont(internalFonts[index], openMode, *errorCode);
if (font) {
fontMap[font->Handle()] = font;
*errorCode = 0;
return font->Handle();
} else {
@ -810,7 +839,6 @@ u32 sceFontOpenUserMemory(u32 libHandle, u32 memoryFontAddrPtr, u32 memoryFontLe
Font *f = new Font(fontData, memoryFontLength);
LoadedFont *font = fontLib->OpenFont(f, FONT_OPEN_USERBUFFER, *errorCode);
if (font) {
fontMap[font->Handle()] = font;
*errorCode = 0;
return font->Handle();
} else {
@ -859,7 +887,6 @@ u32 sceFontOpenUserFile(u32 libHandle, const char *fileName, u32 mode, u32 error
FontOpenMode openMode = mode == 0 ? FONT_OPEN_USERFILE_HANDLERS : FONT_OPEN_USERFILE_FULL;
LoadedFont *font = fontLib->OpenFont(f, openMode, *errorCode);
if (font) {
fontMap[font->Handle()] = font;
*errorCode = 0;
return font->Handle();
} else {