diff options
Diffstat (limited to 'engines/wintermute/base/font/base_font_truetype.cpp')
-rw-r--r-- | engines/wintermute/base/font/base_font_truetype.cpp | 103 |
1 files changed, 66 insertions, 37 deletions
diff --git a/engines/wintermute/base/font/base_font_truetype.cpp b/engines/wintermute/base/font/base_font_truetype.cpp index 2fcdebc117..b879e789e3 100644 --- a/engines/wintermute/base/font/base_font_truetype.cpp +++ b/engines/wintermute/base/font/base_font_truetype.cpp @@ -34,7 +34,6 @@ #include "engines/wintermute/base/base_game.h" #include "engines/wintermute/base/base_file_manager.h" #include "engines/wintermute/utils/utils.h" -#include "engines/wintermute/platform_osystem.h" #include "engines/wintermute/wintermute.h" #include "graphics/fonts/ttf.h" #include "graphics/fontman.h" @@ -122,7 +121,7 @@ int BaseFontTT::getTextWidth(const byte *text, int maxLength) { } if (maxLength >= 0 && textStr.size() > (uint32)maxLength) { - textStr = Common::String(textStr.c_str(), (uint32)maxLength); + textStr = WideString(textStr.c_str(), (uint32)maxLength); } //text = text.substr(0, MaxLength); // TODO: Remove @@ -156,19 +155,19 @@ void BaseFontTT::drawText(const byte *text, int x, int y, int width, TTextAlign return; } - WideString textStr = (const char *)text; + WideString textStr; // TODO: Why do we still insist on Widestrings everywhere? - /* if (_gameRef->_textEncoding == TEXT_UTF8) text = StringUtil::Utf8ToWide((char *)Text); - else text = StringUtil::AnsiToWide((char *)Text);*/ // HACK: J.U.L.I.A. uses CP1252, we need to fix that, // And we still don't have any UTF8-support. - if (_gameRef->_textEncoding != TEXT_UTF8) { + if (_gameRef->_textEncoding == TEXT_UTF8) { + textStr = StringUtil::utf8ToWide((const char *)text); + } else { textStr = StringUtil::ansiToWide((const char *)text); } if (maxLength >= 0 && textStr.size() > (uint32)maxLength) { - textStr = Common::String(textStr.c_str(), (uint32)maxLength); + textStr = WideString(textStr.c_str(), (uint32)maxLength); } //text = text.substr(0, MaxLength); // TODO: Remove @@ -227,7 +226,7 @@ void BaseFontTT::drawText(const byte *text, int x, int y, int width, TTextAlign // and paint it if (surface) { Rect32 rc; - BasePlatform::setRect(&rc, 0, 0, surface->getWidth(), surface->getHeight()); + rc.setRect(0, 0, surface->getWidth(), surface->getHeight()); for (uint32 i = 0; i < _layers.size(); i++) { uint32 color = _layers[i]->_color; uint32 origForceAlpha = renderer->_forceAlphaColor; @@ -249,7 +248,7 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width, //TextLineList lines; // TODO: Use WideString-conversion here. //WrapText(text, width, maxHeight, lines); - Common::Array<Common::String> lines; + Common::Array<WideString> lines; _font->wordWrapText(text, width, lines); while (maxHeight > 0 && lines.size() * _lineHeight > maxHeight) { @@ -268,16 +267,17 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width, alignment = Graphics::kTextAlignRight; } - debugC(kWintermuteDebugFont, "%s %d %d %d %d", text.c_str(), RGBCOLGetR(_layers[0]->_color), RGBCOLGetG(_layers[0]->_color), RGBCOLGetB(_layers[0]->_color), RGBCOLGetA(_layers[0]->_color)); + // TODO: This debug call does not work with WideString because text.c_str() returns an uint32 array. + //debugC(kWintermuteDebugFont, "%s %d %d %d %d", text.c_str(), RGBCOLGetR(_layers[0]->_color), RGBCOLGetG(_layers[0]->_color), RGBCOLGetB(_layers[0]->_color), RGBCOLGetA(_layers[0]->_color)); // void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const; Graphics::Surface *surface = new Graphics::Surface(); if (_deletableFont) { // We actually have a TTF - surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24)); + surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), _gameRef->_renderer->getPixelFormat()); } else { // We are using a fallback, they can't do 32bpp surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0)); } uint32 useColor = 0xffffffff; - Common::Array<Common::String>::iterator it; + Common::Array<WideString>::iterator it; int heightOffset = 0; for (it = lines.begin(); it != lines.end(); ++it) { _font->drawString(surface, *it, 0, heightOffset, width, useColor, alignment); @@ -285,7 +285,27 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width, } BaseSurface *retSurface = _gameRef->_renderer->createSurface(); - Graphics::Surface *convertedSurface = surface->convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24)); + Graphics::Surface *convertedSurface = surface->convertTo(_gameRef->_renderer->getPixelFormat()); + + if (_deletableFont) { + // Reconstruct the alpha channel of the font. + + // Since we painted it with color 0xFFFFFFFF onto a black background, + // the alpha channel is gone, but the color value of each pixel corresponds + // to its original alpha value. + + Graphics::PixelFormat format = _gameRef->_renderer->getPixelFormat(); + uint32 *pixels = (uint32 *)convertedSurface->getPixels(); + + // This is a Surface we created ourselves, so no empty space between rows. + for (int i = 0; i < surface->w * surface->h; ++i) { + uint8 a, r, g, b; + format.colorToRGB(*pixels, r, g, b); + a = r; + *pixels++ = format.ARGBToColor(a, r, g, b); + } + } + retSurface->putSurface(*convertedSurface, true); convertedSurface->free(); surface->free(); @@ -304,7 +324,7 @@ int BaseFontTT::getLetterHeight() { ////////////////////////////////////////////////////////////////////// bool BaseFontTT::loadFile(const Common::String &filename) { - byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); + char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename); if (buffer == nullptr) { _gameRef->LOG(0, "BaseFontTT::LoadFile failed for file '%s'", filename.c_str()); return STATUS_FAILED; @@ -341,7 +361,7 @@ TOKEN_DEF(OFFSET_X) TOKEN_DEF(OFFSET_Y) TOKEN_DEF_END ////////////////////////////////////////////////////////////////////// -bool BaseFontTT::loadBuffer(byte *buffer) { +bool BaseFontTT::loadBuffer(char *buffer) { TOKEN_TABLE_START(commands) TOKEN_TABLE(TTFONT) TOKEN_TABLE(SIZE) @@ -361,15 +381,15 @@ bool BaseFontTT::loadBuffer(byte *buffer) { int cmd; BaseParser parser; - if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_TTFONT) { + if (parser.getCommand(&buffer, commands, ¶ms) != TOKEN_TTFONT) { _gameRef->LOG(0, "'TTFONT' keyword expected."); return STATUS_FAILED; } - buffer = (byte *)params; + buffer = params; uint32 baseColor = 0x00000000; - while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { + while ((cmd = parser.getCommand(&buffer, commands, ¶ms)) > 0) { switch (cmd) { case TOKEN_SIZE: parser.scanStr(params, "%d", &_fontHeight); @@ -419,7 +439,7 @@ bool BaseFontTT::loadBuffer(byte *buffer) { case TOKEN_LAYER: { BaseTTFontLayer *layer = new BaseTTFontLayer; - if (layer && DID_SUCCEED(parseLayer(layer, (byte *)params))) { + if (layer && DID_SUCCEED(parseLayer(layer, params))) { _layers.add(layer); } else { delete layer; @@ -452,7 +472,7 @@ bool BaseFontTT::loadBuffer(byte *buffer) { ////////////////////////////////////////////////////////////////////////// -bool BaseFontTT::parseLayer(BaseTTFontLayer *layer, byte *buffer) { +bool BaseFontTT::parseLayer(BaseTTFontLayer *layer, char *buffer) { TOKEN_TABLE_START(commands) TOKEN_TABLE(OFFSET_X) TOKEN_TABLE(OFFSET_Y) @@ -464,7 +484,7 @@ bool BaseFontTT::parseLayer(BaseTTFontLayer *layer, byte *buffer) { int cmd; BaseParser parser; - while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { + while ((cmd = parser.getCommand(&buffer, commands, ¶ms)) > 0) { switch (cmd) { case TOKEN_OFFSET_X: parser.scanStr(params, "%d", &layer->_offsetX); @@ -501,25 +521,25 @@ bool BaseFontTT::parseLayer(BaseTTFontLayer *layer, byte *buffer) { bool BaseFontTT::persist(BasePersistenceManager *persistMgr) { BaseFont::persist(persistMgr); - persistMgr->transfer(TMEMBER(_isBold)); - persistMgr->transfer(TMEMBER(_isItalic)); - persistMgr->transfer(TMEMBER(_isUnderline)); - persistMgr->transfer(TMEMBER(_isStriked)); - persistMgr->transfer(TMEMBER(_fontHeight)); - persistMgr->transfer(TMEMBER(_fontFile)); + persistMgr->transferBool(TMEMBER(_isBold)); + persistMgr->transferBool(TMEMBER(_isItalic)); + persistMgr->transferBool(TMEMBER(_isUnderline)); + persistMgr->transferBool(TMEMBER(_isStriked)); + persistMgr->transferSint32(TMEMBER(_fontHeight)); + persistMgr->transferCharPtr(TMEMBER(_fontFile)); // persist layers int32 numLayers; if (persistMgr->getIsSaving()) { numLayers = _layers.size(); - persistMgr->transfer(TMEMBER(numLayers)); + persistMgr->transferSint32(TMEMBER(numLayers)); for (int i = 0; i < numLayers; i++) { _layers[i]->persist(persistMgr); } } else { numLayers = _layers.size(); - persistMgr->transfer(TMEMBER(numLayers)); + persistMgr->transferSint32(TMEMBER(numLayers)); for (int i = 0; i < numLayers; i++) { BaseTTFontLayer *layer = new BaseTTFontLayer; layer->persist(persistMgr); @@ -549,17 +569,26 @@ bool BaseFontTT::initFont() { return STATUS_FAILED; } #ifdef USE_FREETYPE2 + Common::String fallbackFilename; + // Handle Bold atleast for the fallback-case. + // TODO: Handle italic. (Needs a test-case) + if (_isBold) { + fallbackFilename = "FreeSansBold.ttf"; + } else { + fallbackFilename = "FreeSans.ttf"; + } + Common::SeekableReadStream *file = BaseFileManager::getEngineInstance()->openFile(_fontFile); if (!file) { if (Common::String(_fontFile) != "arial.ttf") { warning("%s has no replacement font yet, using FreeSans for now (if available)", _fontFile); } // Fallback1: Try to find FreeSans.ttf - file = SearchMan.createReadStreamForMember("FreeSans.ttf"); + file = SearchMan.createReadStreamForMember(fallbackFilename); } if (file) { - _deletableFont = Graphics::loadTTFFont(*file, 96, _fontHeight); // Use the same dpi as WME (96 vs 72). + _deletableFont = Graphics::loadTTFFont(*file, _fontHeight, 96); // Use the same dpi as WME (96 vs 72). _font = _deletableFont; BaseFileManager::getEngineInstance()->closeFile(file); file = nullptr; @@ -582,9 +611,9 @@ bool BaseFontTT::initFont() { } if (themeFile) { Common::Archive *themeArchive = Common::makeZipArchive(themeFile); - if (themeArchive->hasFile("FreeSans.ttf")) { + if (themeArchive->hasFile(fallbackFilename)) { file = nullptr; - file = themeArchive->createReadStreamForMember("FreeSans.ttf"); + file = themeArchive->createReadStreamForMember(fallbackFilename); _deletableFont = Graphics::loadTTFFont(*file, 96, _fontHeight); // Use the same dpi as WME (96 vs 72). _font = _deletableFont; } @@ -599,7 +628,7 @@ bool BaseFontTT::initFont() { // Fallback3: Try to ask FontMan for the FreeSans.ttf ScummModern.zip uses: if (!_font) { // Really not desireable, as we will get a font with dpi-72 then - Common::String fontName = Common::String::format("%s-%s@%d", "FreeSans.ttf", "ASCII", _fontHeight); + Common::String fontName = Common::String::format("%s-%s@%d", fallbackFilename.c_str(), "ASCII", _fontHeight); warning("Looking for %s", fontName.c_str()); _font = FontMan.getFontByName(fontName); } @@ -619,9 +648,9 @@ void BaseFontTT::measureText(const WideString &text, int maxWidth, int maxHeight //TextLineList lines; if (maxWidth >= 0) { - Common::Array<Common::String> lines; + Common::Array<WideString> lines; _font->wordWrapText(text, maxWidth, lines); - Common::Array<Common::String>::iterator it; + Common::Array<WideString>::iterator it; textWidth = 0; for (it = lines.begin(); it != lines.end(); ++it) { textWidth = MAX(textWidth, _font->getStringWidth(*it)); @@ -644,4 +673,4 @@ void BaseFontTT::measureText(const WideString &text, int maxWidth, int maxHeight }*/ } -} // end of namespace Wintermute +} // End of namespace Wintermute |