mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-03 17:33:05 +00:00
GRAPHICS: Use custom stream callbacks for loading TTF fonts
This commit is contained in:
parent
431903a8c0
commit
7e0dfe0081
@ -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.");
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -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)) {
|
||||
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<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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user