diff --git a/engines/bladerunner/subtitles.cpp b/engines/bladerunner/subtitles.cpp index 94e1950e5e4..4730667a47f 100644 --- a/engines/bladerunner/subtitles.cpp +++ b/engines/bladerunner/subtitles.cpp @@ -258,8 +258,8 @@ void Subtitles::init(void) { _useUTF8 = false; } else if (_subtitlesInfo.fontType == Subtitles::kSubtitlesFontTypeTTF) { #if defined(USE_FREETYPE2) - Common::ScopedPtr stream(_vm->getResourceStream(_subtitlesInfo.fontName)); - _font = Graphics::loadTTFFont(*stream, 18); + Common::SeekableReadStream *stream = _vm->getResourceStream(_subtitlesInfo.fontName); + _font = Graphics::loadTTFFont(stream, DisposeAfterUse::YES, 18); _useUTF8 = true; #else warning("Subtitles require a TTF font but this ScummVM build doesn't support it."); diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp index c058491011b..3fc2e60aae8 100644 --- a/engines/buried/graphics.cpp +++ b/engines/buried/graphics.cpp @@ -113,9 +113,7 @@ Graphics::Font *GraphicsManager::createArialFont(int size, bool bold) const { Graphics::Font *font; if (stream) { - font = Graphics::loadTTFFont(*stream, size, Graphics::kTTFSizeModeCharacter, 96, 96, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome); - - delete stream; + font = Graphics::loadTTFFont(stream, DisposeAfterUse::YES, size, Graphics::kTTFSizeModeCharacter, 96, 96, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome); } else { const char *fname; if (bold) @@ -591,7 +589,7 @@ Graphics::Font *GraphicsManager::createMSGothicFont(int size, bool bold) const { // TODO: Fake a bold version if (stream) { // Force monochrome, since the original uses the bitmap glyphs in the font - font = Graphics::loadTTFFont(*stream, size, Graphics::kTTFSizeModeCharacter, 96, 96, Graphics::kTTFRenderModeMonochrome); + font = Graphics::loadTTFFont(stream, DisposeAfterUse::YES, size, Graphics::kTTFSizeModeCharacter, 96, 96, Graphics::kTTFRenderModeMonochrome); } else { font = Graphics::loadTTFFontFromArchive("VL-Gothic-Regular.ttf", size, Graphics::kTTFSizeModeCharacter, 96, 96, Graphics::kTTFRenderModeMonochrome); } @@ -599,7 +597,6 @@ Graphics::Font *GraphicsManager::createMSGothicFont(int size, bool bold) const { if (!font) error("Failed to load MS Gothic font"); - delete stream; return font; } diff --git a/engines/crab/text/TextManager.cpp b/engines/crab/text/TextManager.cpp index ff53864aeab..37441ec1350 100644 --- a/engines/crab/text/TextManager.cpp +++ b/engines/crab/text/TextManager.cpp @@ -70,9 +70,9 @@ void TextManager::init() { uint pos = stringToNumber(id->value()); if (_font.size() <= pos) _font.resize(pos + 1); - Common::File file; - fileOpen(path->value(), &file); - _font[pos] = Graphics::loadTTFFont(file, stringToNumber(size->value())); + Common::File *file = new Common::File(); + fileOpen(path->value(), file); + _font[pos] = Graphics::loadTTFFont(file, DisposeAfterUse::YES, stringToNumber(size->value())); } } } diff --git a/engines/glk/screen.cpp b/engines/glk/screen.cpp index e7378191af7..3fa0551126f 100644 --- a/engines/glk/screen.cpp +++ b/engines/glk/screen.cpp @@ -120,16 +120,16 @@ void Screen::loadFonts(Common::Archive *archive) { } const Graphics::Font *Screen::loadFont(FACES face, Common::Archive *archive, double size, double aspect, int style) { - Common::File f; + Common::File *f = new Common::File(); const char *const FILENAMES[8] = { "GoMono-Regular.ttf", "GoMono-Bold.ttf", "GoMono-Italic.ttf", "GoMono-Bold-Italic.ttf", "NotoSerif-Regular.ttf", "NotoSerif-Bold.ttf", "NotoSerif-Italic.ttf", "NotoSerif-Bold-Italic.ttf" }; - if (!f.open(FILENAMES[face], *archive)) + if (!f->open(FILENAMES[face], *archive)) error("Could not load %s from fonts file", FILENAMES[face]); - return Graphics::loadTTFFont(f, (int)size, Graphics::kTTFSizeModeCharacter); + return Graphics::loadTTFFont(f, DisposeAfterUse::YES, (int)size, Graphics::kTTFSizeModeCharacter); } FACES Screen::getFontId(const Common::String &name) { diff --git a/engines/glk/zcode/screen.cpp b/engines/glk/zcode/screen.cpp index 97d9e46b87f..a16bc686d38 100644 --- a/engines/glk/zcode/screen.cpp +++ b/engines/glk/zcode/screen.cpp @@ -117,12 +117,11 @@ void FrotzScreen::loadExtraFonts(Common::Archive *archive) { // Add Runic font. It provides cleaner versions of the runic characters in the // character graphics font - Common::File f; - if (!f.open("NotoSansRunic-Regular.ttf", *archive)) + Common::File *f = new Common::File(); + if (!f->open("NotoSansRunic-Regular.ttf", *archive)) error("Could not load font"); - _fonts.push_back(Graphics::loadTTFFont(f, g_conf->_propInfo._size, Graphics::kTTFSizeModeCharacter)); - f.close(); + _fonts.push_back(Graphics::loadTTFFont(f, DisposeAfterUse::YES, g_conf->_propInfo._size, Graphics::kTTFSizeModeCharacter)); } } // End of namespace ZCode diff --git a/engines/gnap/gnap.cpp b/engines/gnap/gnap.cpp index 78a38f5bf64..659f8763af4 100644 --- a/engines/gnap/gnap.cpp +++ b/engines/gnap/gnap.cpp @@ -234,10 +234,9 @@ Common::Error GnapEngine::run() { #ifdef USE_FREETYPE2 Common::SeekableReadStream *stream = _exe->getResource(Common::kWinFont, 2000); - _font = Graphics::loadTTFFont(*stream, 24); + _font = Graphics::loadTTFFont(stream, DisposeAfterUse::YES, 24); if (!_font) warning("Unable to load font"); - delete stream; #else _font = nullptr; #endif diff --git a/engines/grim/font.cpp b/engines/grim/font.cpp index c98b07f1e0b..cbdfe83b250 100644 --- a/engines/grim/font.cpp +++ b/engines/grim/font.cpp @@ -378,7 +378,6 @@ void FontTTF::restoreState(SaveGame *state) { stream = g_resourceloader->openNewStreamFile(fname.c_str(), true); loadTTF(fname, stream, size); } - delete stream; } void BitmapFont::render(Graphics::Surface &buf, const Common::String ¤tLine, @@ -420,7 +419,7 @@ void FontTTF::loadTTF(const Common::String &filename, Common::SeekableReadStream _filename = filename; _size = size; #ifdef USE_FREETYPE2 - _font = Graphics::loadTTFFont(*data, size); + _font = Graphics::loadTTFFont(data, DisposeAfterUse::YES, size); #else _font = nullptr; #endif diff --git a/engines/mohawk/myst_graphics.cpp b/engines/mohawk/myst_graphics.cpp index 1ce4b7d5fb2..1408b5bb507 100644 --- a/engines/mohawk/myst_graphics.cpp +++ b/engines/mohawk/myst_graphics.cpp @@ -94,8 +94,7 @@ void MystGraphics::loadMenuFont() { Common::SeekableReadStream *fontStream = SearchMan.createReadStreamForMember(menuFontName); if (fontStream) { - _menuFont = Graphics::loadTTFFont(*fontStream, fontSize); - delete fontStream; + _menuFont = Graphics::loadTTFFont(fontStream, DisposeAfterUse::YES, fontSize); } else #endif { diff --git a/engines/mohawk/riven_graphics.cpp b/engines/mohawk/riven_graphics.cpp index ccecbb5c010..5de883cb8cc 100644 --- a/engines/mohawk/riven_graphics.cpp +++ b/engines/mohawk/riven_graphics.cpp @@ -824,8 +824,7 @@ void RivenGraphics::loadMenuFont() { Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(fontName); if (stream) { - _menuFont = Graphics::loadTTFFont(*stream, fontHeight); - delete stream; + _menuFont = Graphics::loadTTFFont(stream, DisposeAfterUse::YES, fontHeight); } #endif diff --git a/engines/myst3/subtitles.cpp b/engines/myst3/subtitles.cpp index 4bbefd86d99..ee2a2c76ec1 100644 --- a/engines/myst3/subtitles.cpp +++ b/engines/myst3/subtitles.cpp @@ -97,8 +97,7 @@ void FontSubtitles::loadResources() { Common::SeekableReadStream *s = SearchMan.createReadStreamForMember(ttfFile); if (s) { - _font = Graphics::loadTTFFont(*s, _fontSize * _scale); - delete s; + _font = Graphics::loadTTFFont(s, DisposeAfterUse::YES, _fontSize * _scale); } else { warning("Unable to load the subtitles font '%s'", ttfFile); } diff --git a/engines/stark/services/fontprovider.cpp b/engines/stark/services/fontprovider.cpp index dee4e1f91ec..68ea3d763e1 100644 --- a/engines/stark/services/fontprovider.cpp +++ b/engines/stark/services/fontprovider.cpp @@ -135,9 +135,8 @@ FontProvider::FontHolder::FontHolder(FontProvider *fontProvider, const Common::S bool stemDarkening = StarkSettings->isFontAntialiasingEnabled(); _font = Common::SharedPtr( - Graphics::loadTTFFont(*s, _scaledHeight, Graphics::kTTFSizeModeCell, 0, 0, renderMode, nullptr, stemDarkening) + Graphics::loadTTFFont(s, DisposeAfterUse::YES, _scaledHeight, Graphics::kTTFSizeModeCell, 0, 0, renderMode, nullptr, stemDarkening) ); - delete s; } else { warning("Unable to load the font '%s'", ttfFileName.toString().c_str()); } diff --git a/engines/tetraedge/te/te_font3.cpp b/engines/tetraedge/te/te_font3.cpp index 6edce9467d6..7667ef6cc31 100644 --- a/engines/tetraedge/te/te_font3.cpp +++ b/engines/tetraedge/te/te_font3.cpp @@ -46,7 +46,7 @@ Graphics::Font *TeFont3::getAtSize(uint size) { error("TeFont3::: Couldn't open font file %s.", getAccessName().toString(Common::Path::kNativeSeparator).c_str()); _fontFile.seek(0); - Graphics::Font *newFont = Graphics::loadTTFFont(_fontFile, size, Graphics::kTTFSizeModeCharacter, 0, 0, Graphics::kTTFRenderModeNormal); + Graphics::Font *newFont = Graphics::loadTTFFont(&_fontFile, DisposeAfterUse::NO, size, Graphics::kTTFSizeModeCharacter, 0, 0, Graphics::kTTFRenderModeNormal); if (!newFont) { error("TeFont3::: Couldn't load font %s at size %d.", _loadedPath.toString(Common::Path::kNativeSeparator).c_str(), size); } diff --git a/engines/ultima/ultima8/gfx/fonts/font_manager.cpp b/engines/ultima/ultima8/gfx/fonts/font_manager.cpp index bd277d4cd3a..263c5ad760e 100644 --- a/engines/ultima/ultima8/gfx/fonts/font_manager.cpp +++ b/engines/ultima/ultima8/gfx/fonts/font_manager.cpp @@ -90,6 +90,7 @@ Font *FontManager::getTTFont(unsigned int fontnum) { Graphics::Font *FontManager::getTTF_Font(const Common::Path &filename, int pointsize, bool antialiasing) { +#ifdef USE_FREETYPE2 TTFId id; id._filename = filename; id._pointSize = pointsize; @@ -100,20 +101,21 @@ Graphics::Font *FontManager::getTTF_Font(const Common::Path &filename, int point if (iter != _ttfFonts.end()) return iter->_value; - Common::File fontids; - if (!fontids.open(filename)) { + Common::File* fontids = new Common::File(); + if (!fontids->open(filename)) { warning("Failed to open TTF: %s", filename.toString().c_str()); + delete fontids; return nullptr; } -#ifdef USE_FREETYPE2 // open font using ScummVM TTF API // Note: The RWops and ReadStream will be deleted by the TTF_Font Graphics::TTFRenderMode mode = antialiasing ? Graphics::kTTFRenderModeNormal : Graphics::kTTFRenderModeMonochrome; - Graphics::Font *font = Graphics::loadTTFFont(fontids, pointsize, Graphics::kTTFSizeModeCharacter, 0, 0, mode, 0, false); + Graphics::Font *font = Graphics::loadTTFFont(fontids, DisposeAfterUse::YES, pointsize, Graphics::kTTFSizeModeCharacter, 0, 0, mode, 0, false); if (!font) { warning("Failed to open TTF: %s", filename.toString().c_str()); + delete fontids; return nullptr; } diff --git a/engines/vcruise/runtime.cpp b/engines/vcruise/runtime.cpp index f0b747268ba..f1fad9b84c1 100644 --- a/engines/vcruise/runtime.cpp +++ b/engines/vcruise/runtime.cpp @@ -1501,9 +1501,11 @@ Runtime::Runtime(OSystem *system, Audio::Mixer *mixer, MidiDriver *midiDrv, cons #ifdef USE_FREETYPE2 if (_gameID == GID_AD2044) { - Common::File f; - if (f.open("gfx/AD2044.TTF")) - _subtitleFontKeepalive.reset(Graphics::loadTTFFont(f, 16, Graphics::kTTFSizeModeCharacter, 108, 72, Graphics::kTTFRenderModeLight)); + Common::File *f = new Common::File(); + if (f->open("gfx/AD2044.TTF")) + _subtitleFontKeepalive.reset(Graphics::loadTTFFont(f, DisposeAfterUse::YES, 16, Graphics::kTTFSizeModeCharacter, 108, 72, Graphics::kTTFRenderModeLight)); + else + delete f; } else _subtitleFontKeepalive.reset(Graphics::loadTTFFontFromArchive("NotoSans-Regular.ttf", 16, Graphics::kTTFSizeModeCharacter, 0, 0, Graphics::kTTFRenderModeLight)); diff --git a/engines/wintermute/base/font/base_font_truetype.cpp b/engines/wintermute/base/font/base_font_truetype.cpp index aa2846ebc77..6e0a6623e23 100644 --- a/engines/wintermute/base/font/base_font_truetype.cpp +++ b/engines/wintermute/base/font/base_font_truetype.cpp @@ -583,7 +583,7 @@ bool BaseFontTT::initFont() { fallbackFilename = "FreeSans.ttf"; } - Common::SeekableReadStream *file = BaseFileManager::getEngineInstance()->openFile(_fontFile); + Common::SeekableReadStream *file = BaseFileManager::getEngineInstance()->openFile(_fontFile, true, false); if (!file) { if (Common::String(_fontFile) != "arial.ttf") { warning("%s has no replacement font yet, using FreeSans for now (if available)", _fontFile); @@ -593,10 +593,8 @@ bool BaseFontTT::initFont() { } if (file) { - _deletableFont = Graphics::loadTTFFont(*file, _fontHeight, Graphics::kTTFSizeModeCharacter, 96); // Use the same dpi as WME (96 vs 72). + _deletableFont = Graphics::loadTTFFont(file, DisposeAfterUse::YES, _fontHeight, Graphics::kTTFSizeModeCharacter, 96); // Use the same dpi as WME (96 vs 72). _font = _deletableFont; - BaseFileManager::getEngineInstance()->closeFile(file); - file = nullptr; } // Fallback2: Try load the font from the common fonts archive: diff --git a/engines/zvision/text/truetype_font.cpp b/engines/zvision/text/truetype_font.cpp index 1f1cbd8786d..c30ffe2355b 100644 --- a/engines/zvision/text/truetype_font.cpp +++ b/engines/zvision/text/truetype_font.cpp @@ -117,14 +117,15 @@ bool StyledTTFont::loadFont(const Common::String &fontName, int32 point, uint st bool sharp = (_style & TTF_STYLE_SHARP) == TTF_STYLE_SHARP; - Common::File file; + Common::File *file = new Common::File(); Graphics::Font *newFont; - if (!file.open(Common::Path(newFontName)) && !_engine->getSearchManager()->openFile(file, Common::Path(newFontName)) && - !file.open(Common::Path(liberationFontName)) && !_engine->getSearchManager()->openFile(file, Common::Path(liberationFontName)) && - !file.open(Common::Path(freeFontName)) && !_engine->getSearchManager()->openFile(file, Common::Path(freeFontName))) { + if (!file->open(Common::Path(newFontName)) && !_engine->getSearchManager()->openFile(*file, Common::Path(newFontName)) && + !file->open(Common::Path(liberationFontName)) && !_engine->getSearchManager()->openFile(*file, Common::Path(liberationFontName)) && + !file->open(Common::Path(freeFontName)) && !_engine->getSearchManager()->openFile(*file, Common::Path(freeFontName))) { newFont = Graphics::loadTTFFontFromArchive(liberationFontName, point, Graphics::kTTFSizeModeCell, 0, 0, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); + delete file; } else { - newFont = Graphics::loadTTFFont(file, point, Graphics::kTTFSizeModeCell, 0, 0, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); + newFont = Graphics::loadTTFFont(file, DisposeAfterUse::YES, point, Graphics::kTTFSizeModeCell, 0, 0, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); } if (newFont == nullptr) { diff --git a/graphics/fonts/ttf.cpp b/graphics/fonts/ttf.cpp index ec01a56af87..8d5afd7d09c 100644 --- a/graphics/fonts/ttf.cpp +++ b/graphics/fonts/ttf.cpp @@ -99,11 +99,13 @@ public: */ bool isInitialized() const { return _initialized; } - bool loadFont(const uint8 *file, const int32 face_index, const uint32 size, FT_Face &face); + bool loadFont(Common::SeekableReadStream *ttfFile, FT_Stream stream, const int32 face_index, FT_Face &face); void closeFont(FT_Face &face); private: FT_Library _library; bool _initialized; + + static unsigned long readCallback(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count); }; void shutdownTTF() { @@ -124,10 +126,19 @@ TTFLibrary::~TTFLibrary() { } } -bool TTFLibrary::loadFont(const uint8 *file, const int32 face_index, const uint32 size, FT_Face &face) { +bool TTFLibrary::loadFont(Common::SeekableReadStream *ttfFile, FT_Stream stream, const int32 face_index, FT_Face &face) { assert(_initialized); - return (FT_New_Memory_Face(_library, file, size, face_index, &face) == 0); + FT_Open_Args args; + args.flags = FT_OPEN_STREAM; + args.stream = stream; + + stream->read = readCallback; + stream->descriptor.pointer = ttfFile; + stream->pos = ttfFile->pos(); + stream->size = ttfFile->size() - stream->pos; + + return (FT_Open_Face(_library, &args, face_index, &face) == 0); } void TTFLibrary::closeFont(FT_Face &face) { @@ -136,15 +147,20 @@ void TTFLibrary::closeFont(FT_Face &face) { FT_Done_Face(face); } +unsigned long TTFLibrary::readCallback(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) { + Common::SeekableReadStream *ttfFile = (Common::SeekableReadStream *)stream->descriptor.pointer; + ttfFile->seek(offset); + return ttfFile->read(buffer, count); +} + class TTFFont : public Font { public: TTFFont(); ~TTFFont() override; - bool load(Common::SeekableReadStream &stream, int size, TTFSizeMode sizeMode, - uint xdpi, uint ydpi, TTFRenderMode renderMode, const uint32 *mapping, bool stemDarkening); - bool load(uint8 *ttfFile, uint32 sizeFile, int32 faceIndex, bool fakeBold, bool fakeItalic, - int size, TTFSizeMode sizeMode, uint xdpi, uint ydpi, TTFRenderMode renderMode, const uint32 *mapping, bool stemDarkening); + bool load(Common::SeekableReadStream *ttfFile, DisposeAfterUse::Flag disposeAfterUse, int size, TTFSizeMode sizeMode, + uint xdpi, uint ydpi, TTFRenderMode renderMode, const uint32 *mapping, bool stemDarkening, + int32 faceIndex = 0, bool fakeBold = false, bool fakeItalic = false); int getFontHeight() const override; Common::String getFontName() const override; @@ -163,10 +179,11 @@ public: private: bool _initialized; + FT_StreamRec_ _stream; FT_Face _face; - uint8 *_ttfFile; - uint32 _size; + Common::SeekableReadStream *_ttfFile; + DisposeAfterUse::Flag _disposeAfterUse; int _width, _height; int _ascent, _descent; @@ -201,16 +218,18 @@ private: }; TTFFont::TTFFont() - : _initialized(false), _face(), _ttfFile(0), _size(0), _width(0), _height(0), _ascent(0), + : _initialized(false), _stream(), _face(), _ttfFile(0), _width(0), _height(0), _ascent(0), _descent(0), _glyphs(), _loadFlags(FT_LOAD_TARGET_NORMAL), _renderMode(FT_RENDER_MODE_NORMAL), - _hasKerning(false), _allowLateCaching(false), _fakeBold(false), _fakeItalic(false) { + _hasKerning(false), _allowLateCaching(false), _fakeBold(false), _fakeItalic(false), + _disposeAfterUse(DisposeAfterUse::NO) { } TTFFont::~TTFFont() { if (_initialized) { g_ttf.closeFont(_face); - delete[] _ttfFile; + if (_disposeAfterUse == DisposeAfterUse::YES) + delete _ttfFile; _ttfFile = 0; for (GlyphCache::iterator i = _glyphs.begin(), end = _glyphs.end(); i != end; ++i) @@ -220,50 +239,21 @@ TTFFont::~TTFFont() { } } -bool TTFFont::load(Common::SeekableReadStream &stream, int size, TTFSizeMode sizeMode, - uint xdpi, uint ydpi, TTFRenderMode renderMode, const uint32 *mapping, bool stemDarkening) { - if (!g_ttf.isInitialized()) - return false; - uint32 sizeFile = stream.size(); - if (!sizeFile) - return false; - - uint8 *ttfFile = new uint8[sizeFile]; - assert(ttfFile); - - if (stream.read(ttfFile, sizeFile) != sizeFile) { - delete[] ttfFile; - return false; - } - - if (!load(ttfFile, sizeFile, 0, false, false, size, sizeMode, xdpi, ydpi, renderMode, mapping, stemDarkening)) { - delete[] ttfFile; - return false; - } - - // Don't delete ttfFile as it's now owned by the class - return true; -} - -bool TTFFont::load(uint8 *ttfFile, uint32 sizeFile, int32 faceIndex, bool bold, bool italic, - int size, TTFSizeMode sizeMode, uint xdpi, uint ydpi, TTFRenderMode renderMode, const uint32 *mapping, bool stemDarkening) { +bool TTFFont::load(Common::SeekableReadStream *ttfFile, DisposeAfterUse::Flag disposeAfterUse, int size, TTFSizeMode sizeMode, + uint xdpi, uint ydpi, TTFRenderMode renderMode, const uint32 *mapping, bool stemDarkening, + int32 faceIndex, bool bold, bool italic) { _initialized = false; if (!g_ttf.isInitialized()) return false; - _size = sizeFile; - if (!_size) - return false; - _ttfFile = ttfFile; assert(_ttfFile); - if (!g_ttf.loadFont(_ttfFile, faceIndex, _size, _face)) { - // Don't delete ttfFile as we return fail - _ttfFile = 0; + _disposeAfterUse = disposeAfterUse; + if (!g_ttf.loadFont(_ttfFile, &_stream, faceIndex, _face)) { return false; } @@ -879,10 +869,10 @@ void TTFFont::assureCached(uint32 chr) const { } } -Font *loadTTFFont(Common::SeekableReadStream &stream, int size, TTFSizeMode sizeMode, uint xdpi, uint ydpi, TTFRenderMode renderMode, const uint32 *mapping, bool stemDarkening) { +Font *loadTTFFont(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, int size, TTFSizeMode sizeMode, uint xdpi, uint ydpi, TTFRenderMode renderMode, const uint32 *mapping, bool stemDarkening) { TTFFont *font = new TTFFont(); - if (!font->load(stream, size, sizeMode, xdpi, ydpi, renderMode, mapping, stemDarkening)) { + if (!font->load(stream, disposeAfterUse, size, sizeMode, xdpi, ydpi, renderMode, mapping, stemDarkening)) { delete font; return 0; } @@ -906,9 +896,9 @@ Font *loadTTFFontFromArchive(const Common::String &filename, int size, TTFSizeMo return nullptr; } - Common::File f; + Common::File *f = new Common::File(); - if (!f.open(Common::Path(filename, Common::Path::kNoSeparator), *archive)) { + if (!f->open(Common::Path(filename, Common::Path::kNoSeparator), *archive)) { delete archive; archiveStream = nullptr; @@ -924,17 +914,25 @@ Font *loadTTFFontFromArchive(const Common::String &filename, int size, TTFSizeMo archive = Common::makeZipArchive(archiveStream); if (!archive) { + delete f; return nullptr; } - if (!f.open(Common::Path(filename, Common::Path::kNoSeparator), *archive)) { + if (!f->open(Common::Path(filename, Common::Path::kNoSeparator), *archive)) { delete archive; + delete f; return nullptr; } } - Font *font = loadTTFFont(f, size, sizeMode, xdpi, ydpi, renderMode, mapping); + Font *font = loadTTFFont(f, DisposeAfterUse::YES, size, sizeMode, xdpi, ydpi, renderMode, mapping); + if (!font) { + delete archive; + delete f; + return nullptr; + } + // HACK: We currently assume that ZipArchive always loads the whole file into memory, so we can delete the archive here. delete archive; return font; } @@ -990,37 +988,22 @@ Font *findTTFace(const Common::Array &files, const Common::U32Stri if (!g_ttf.isInitialized()) return nullptr; - uint8 *bestTTFFile = nullptr; - uint32 bestSize = 0; + Common::SeekableReadStream *bestTTFFile = nullptr; uint32 bestFaceId = (uint32) -1; uint32 bestPenalty = (uint32) -1; for (Common::Array::const_iterator it = files.begin(); it != files.end(); it++) { - Common::File ttf; - if (!ttf.open(*it)) { - continue; - } - uint32 sizeFile = ttf.size(); - if (!sizeFile) { - continue; - } - uint8 *ttfFile = new uint8[sizeFile]; - assert(ttfFile); - - if (ttf.read(ttfFile, sizeFile) != sizeFile) { - delete[] ttfFile; - ttfFile = 0; - + Common::File *ttfFile = new Common::File(); + if (!ttfFile->open(*it)) { continue; } - ttf.close(); - + FT_StreamRec_ stream; FT_Face face; // Load face index -1 to get the count - if (!g_ttf.loadFont(ttfFile, -1, sizeFile, face)) { - delete[] ttfFile; + if (!g_ttf.loadFont(ttfFile, &stream, -1, face)) { + delete ttfFile; ttfFile = 0; continue; @@ -1031,7 +1014,7 @@ Font *findTTFace(const Common::Array &files, const Common::U32Stri g_ttf.closeFont(face); for (FT_Long i = 0; i < num_faces; i++) { - if (!g_ttf.loadFont(ttfFile, i, sizeFile, face)) { + if (!g_ttf.loadFont(ttfFile, &stream, i, face)) { continue; } @@ -1059,19 +1042,18 @@ Font *findTTFace(const Common::Array &files, const Common::U32Stri // Better font // Cleanup old best font if it's not the same file as the current one if (bestTTFFile != ttfFile) { - delete [] bestTTFFile; + delete bestTTFFile; } bestPenalty = penalty; bestTTFFile = ttfFile; bestFaceId = i; - bestSize = sizeFile; } } // Don't free the file if it has been elected the best if (bestTTFFile != ttfFile) { - delete [] ttfFile; + delete ttfFile; } ttfFile = nullptr; } @@ -1094,10 +1076,10 @@ Font *findTTFace(const Common::Array &files, const Common::U32Stri ydpi = xdpi; } - if (!font->load(bestTTFFile, bestSize, bestFaceId, bold, italic, size, sizeMode, - xdpi, ydpi, renderMode, mapping, false)) { + if (!font->load(bestTTFFile, DisposeAfterUse::YES, size, sizeMode, xdpi, ydpi, + renderMode, mapping, false, bestFaceId, bold, italic)) { delete font; - delete [] bestTTFFile; + delete bestTTFFile; return nullptr; } diff --git a/graphics/fonts/ttf.h b/graphics/fonts/ttf.h index 65193b5cd80..d026a96ff23 100644 --- a/graphics/fonts/ttf.h +++ b/graphics/fonts/ttf.h @@ -98,7 +98,7 @@ enum TTFSizeMode { * supported. * @return 0 in case loading fails, otherwise a pointer to the Font object. */ -Font *loadTTFFont(Common::SeekableReadStream &stream, int size, TTFSizeMode sizeMode = kTTFSizeModeCharacter, uint xdpi = 0, uint ydpi = 0, TTFRenderMode renderMode = kTTFRenderModeLight, const uint32 *mapping = 0, bool stemDarkening = false); +Font *loadTTFFont(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, int size, TTFSizeMode sizeMode = kTTFSizeModeCharacter, uint xdpi = 0, uint ydpi = 0, TTFRenderMode renderMode = kTTFRenderModeLight, const uint32 *mapping = 0, bool stemDarkening = false); /** * Loads a TTF font file from the common fonts archive. diff --git a/graphics/macgui/macfontmanager.cpp b/graphics/macgui/macfontmanager.cpp index 146860593e1..2638ab61644 100644 --- a/graphics/macgui/macfontmanager.cpp +++ b/graphics/macgui/macfontmanager.cpp @@ -901,7 +901,7 @@ void MacFontManager::generateTTFFont(MacFont &toFont, Common::SeekableReadStream // TODO: Handle getSlant() flags stream->seek(0); - Font *font = Graphics::loadTTFFont(*stream, toFont.getSize(), Graphics::kTTFSizeModeCharacter, 0, 0, Graphics::kTTFRenderModeMonochrome); + Font *font = Graphics::loadTTFFont(stream, DisposeAfterUse::NO, toFont.getSize(), Graphics::kTTFSizeModeCharacter, 0, 0, Graphics::kTTFRenderModeMonochrome); if (!font) { warning("Failed to generate font '%s'", toPrintable(getFontName(toFont)).c_str()); diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index 9863b95d939..c5feb63aae6 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -1748,11 +1748,12 @@ const Graphics::Font *ThemeEngine::loadScalableFont(const Common::String &filena for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) { Common::SeekableReadStream *stream = (*i)->createReadStream(); if (stream) { - font = Graphics::loadTTFFont(*stream, pointsize, Graphics::kTTFSizeModeCharacter, 0, 0, Graphics::kTTFRenderModeLight); - delete stream; + font = Graphics::loadTTFFont(stream, DisposeAfterUse::YES, pointsize, Graphics::kTTFSizeModeCharacter, 0, 0, Graphics::kTTFRenderModeLight); if (font) return font; + + delete stream; } } diff --git a/video/subtitles.cpp b/video/subtitles.cpp index 99e9f0f25d3..9ad9664b26e 100644 --- a/video/subtitles.cpp +++ b/video/subtitles.cpp @@ -241,13 +241,16 @@ Subtitles::~Subtitles() { } void Subtitles::setFont(const char *fontname, int height) { - Common::File file; - _fontHeight = height; #ifdef USE_FREETYPE2 - if (file.open(fontname)) { - _font = Graphics::loadTTFFont(file, _fontHeight, Graphics::kTTFSizeModeCharacter, 96); + Common::File *file = new Common::File(); + if (file->open(fontname)) { + _font = Graphics::loadTTFFont(file, DisposeAfterUse::YES, _fontHeight, Graphics::kTTFSizeModeCharacter, 96); + if (!_font) + delete file; + } else { + delete file; } if (!_font) {