[Scummvm-git-logs] scummvm master -> 7e0dfe008157838d45be930b43fa587ce55b91c5

ccawley2011 noreply at scummvm.org
Tue Jul 23 14:33:46 UTC 2024


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
7e0dfe0081 GRAPHICS: Use custom stream callbacks for loading TTF fonts


Commit: 7e0dfe008157838d45be930b43fa587ce55b91c5
    https://github.com/scummvm/scummvm/commit/7e0dfe008157838d45be930b43fa587ce55b91c5
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2024-07-23T15:33:43+01:00

Commit Message:
GRAPHICS: Use custom stream callbacks for loading TTF fonts

Changed paths:
    engines/bladerunner/subtitles.cpp
    engines/buried/graphics.cpp
    engines/crab/text/TextManager.cpp
    engines/glk/screen.cpp
    engines/glk/zcode/screen.cpp
    engines/gnap/gnap.cpp
    engines/grim/font.cpp
    engines/mohawk/myst_graphics.cpp
    engines/mohawk/riven_graphics.cpp
    engines/myst3/subtitles.cpp
    engines/stark/services/fontprovider.cpp
    engines/tetraedge/te/te_font3.cpp
    engines/ultima/ultima8/gfx/fonts/font_manager.cpp
    engines/vcruise/runtime.cpp
    engines/wintermute/base/font/base_font_truetype.cpp
    engines/zvision/text/truetype_font.cpp
    graphics/fonts/ttf.cpp
    graphics/fonts/ttf.h
    graphics/macgui/macfontmanager.cpp
    gui/ThemeEngine.cpp
    video/subtitles.cpp


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<Common::SeekableReadStream> 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<uint>(id->value());
 				if (_font.size() <= pos)
 					_font.resize(pos + 1);
-				Common::File file;
-				fileOpen(path->value(), &file);
-				_font[pos] = Graphics::loadTTFFont(file, stringToNumber<int>(size->value()));
+				Common::File *file = new Common::File();
+				fileOpen(path->value(), file);
+				_font[pos] = Graphics::loadTTFFont(file, DisposeAfterUse::YES, stringToNumber<int>(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 &currentLine,
@@ -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::Font>(
-				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<Common::Path> &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<Common::Path>::const_iterator it = files.begin(); it != files.end(); it++) {
-		Common::File ttf;
-		if (!ttf.open(*it)) {
+		Common::File *ttfFile = new Common::File();
+		if (!ttfFile->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;
-
-			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<Common::Path> &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<Common::Path> &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<Common::Path> &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) {




More information about the Scummvm-git-logs mailing list