diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp index e29367834af..50b8f15b4a4 100644 --- a/engines/scumm/dialogs.cpp +++ b/engines/scumm/dialogs.cpp @@ -382,16 +382,23 @@ void HelpDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 da #pragma mark - InfoDialog::InfoDialog(ScummEngine *scumm, int res) -: ScummDialog(0, 0, 0, 0), _vm(scumm) { // dummy x and w +: ScummDialog(0, 0, 0, 0), _vm(scumm), _style(GUI::ThemeEngine::kFontStyleBold) { // dummy x and w _message = queryResString(res); + Common::Language lang = (_vm->_language == Common::KO_KOR || _vm->_language == Common::JA_JPN || + _vm->_language == Common::ZH_TWN || _vm->_language == Common::ZH_CNA) ? _vm->_language : Common::UNK_LANG; + // Width and height are dummy - _text = new GUI::StaticTextWidget(this, 0, 0, 10, 10, _message, kTextAlignCenter); + _text = new GUI::StaticTextWidget(this, 0, 0, 10, 10, _message, kTextAlignCenter, Common::U32String(), GUI::ThemeEngine::kFontStyleBold, lang); + + // Store this for the calls to getStringWidth() and getStringHeight() in reflowLayout(). + if (lang != Common::UNK_LANG) + _style = GUI::ThemeEngine::kFontStyleLangExtra; } InfoDialog::InfoDialog(ScummEngine *scumm, const U32String &message) -: ScummDialog(0, 0, 0, 0), _vm(scumm) { // dummy x and w +: ScummDialog(0, 0, 0, 0), _vm(scumm), _style(GUI::ThemeEngine::kFontStyleBold) { // dummy x and w _message = message; @@ -409,8 +416,8 @@ void InfoDialog::reflowLayout() { const int screenW = g_system->getOverlayWidth(); const int screenH = g_system->getOverlayHeight(); - int width = g_gui.getStringWidth(_message) + 16; - int height = g_gui.getFontHeight() + 8; + int width = g_gui.getStringWidth(_message, _style) + 16; + int height = g_gui.getFontHeight(_style) + 8; _w = width; _h = height; diff --git a/engines/scumm/dialogs.h b/engines/scumm/dialogs.h index d5185a05b52..f8566c0a4f3 100644 --- a/engines/scumm/dialogs.h +++ b/engines/scumm/dialogs.h @@ -72,6 +72,7 @@ protected: ScummEngine *_vm; U32String _message; GUI::StaticTextWidget *_text; + GUI::ThemeEngine::FontStyle _style; public: // arbitrary message diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index c4d5789cb8f..6688d2b515f 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -553,7 +553,7 @@ bool ThemeEngine::addFont(TextData textId, const Common::String &language, const Common::String localized = FontMan.genLocalizedFontFilename(file); const Common::String charset #ifdef USE_TRANSLATION - (TransMan.getCurrentCharset()) + (textId == kTextDataExtraLang ? "" : TransMan.getCurrentCharset()) #endif ; @@ -598,6 +598,63 @@ bool ThemeEngine::addFont(TextData textId, const Common::String &language, const } +// This should work independently of the translation manager, since it is is just about displaying +// correct ingame messages in Chinese, Korean and Japanese games, even if the launcher is set to +// English and/or the translations are disabled. +Common::Array getLangIdentifiers(const Common::String &language) { + struct IdStr2Lang { + const char strId[6]; + Common::Language lang; + }; + + // I have added only the languages that currently make sense (the only other extra font that we + // currently have is for Hindi, but that language is only supported in the launcher, there are + // no games in Hindi). + IdStr2Lang matchPairs[] = { + // { "hi", Common::UNK_LANG }, + { "ja", Common::JA_JPN }, + { "ko", Common::KO_KOR }, + { "zh", Common::ZH_ANY }, + { "zh", Common::ZH_CNA }, + { "zh", Common::ZH_TWN } + }; + + Common::Array result; + + for (int i = 0; i < ARRAYSIZE(matchPairs); ++i) { + if (language.contains(matchPairs[i].strId)) + result.push_back(matchPairs[i].lang); + } + + return result; +} + +void ThemeEngine::storeFontNames(TextData textId, const Common::String &language, const Common::String &file, const Common::String &scalableFile, const int pointsize) { + if (language.empty()) + return; + + Common::Array langs = getLangIdentifiers(language); + if (langs.empty()) + return; + + Common::Array::iterator entry = Common::find(_langExtraFonts.begin(), _langExtraFonts.end(), langs[0]); + if (entry == _langExtraFonts.end()) + _langExtraFonts.push_back(LangExtraFont(textId, langs, file, scalableFile, pointsize)); + else + entry->storeFileNames(textId, file, scalableFile, pointsize); +} + +bool ThemeEngine::loadExtraFont(FontStyle style, Common::Language lang) { + if (style >= kFontStyleMax) + return false; + + Common::Array::iterator entry = Common::find(_langExtraFonts.begin(), _langExtraFonts.end(), lang); + if (entry == _langExtraFonts.end()) + return false; + TextData td = fontStyleToData(style); + return addFont(GUI::TextData::kTextDataExtraLang, Common::String(), entry->file(td), entry->sclFile(td), entry->fntSize(td)); +} + bool ThemeEngine::addTextColor(TextColor colorId, int r, int g, int b) { if (colorId >= kTextColorMAX) return false; diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index 32492a8e31b..87acb61eec6 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -27,6 +27,7 @@ #include "common/fs.h" #include "common/hash-str.h" #include "common/hashmap.h" +#include "common/language.h" #include "common/list.h" #include "common/str.h" #include "common/rect.h" @@ -151,6 +152,7 @@ enum TextData { kTextDataNormalFont, kTextDataTooltip, kTextDataConsole, + kTextDataExtraLang, kTextDataMAX }; @@ -169,6 +171,34 @@ enum TextColor { kTextColorMAX }; +class LangExtraFont { +public: + LangExtraFont(TextData textId, Common::Array &lngs, const Common::String &file, const Common::String &scalableFile, int ps) : _langs(lngs) { + storeFileNames(textId, file, scalableFile, ps); + } + + void storeFileNames(TextData textId, const Common::String &file, const Common::String &scalableFile, int ps) { + assert(textId < kTextDataMAX); + _fontFilesStd[textId] = file; + _fontFilesScalable[textId] = scalableFile; + _fontSize[textId] = ps; + } + + bool operator==(Common::Language l) const { + return (Common::find(_langs.begin(), _langs.end(), l) != _langs.end()); + } + + Common::String file(TextData textId) const { return _fontFilesStd[textId]; } + Common::String sclFile(TextData textId) const { return _fontFilesScalable[textId]; } + int fntSize(TextData textId) const { return _fontSize[textId]; } + +private: + Common::Array _langs; + Common::String _fontFilesStd[kTextDataMAX]; + Common::String _fontFilesScalable[kTextDataMAX]; + int _fontSize[kTextDataMAX]; +}; + class ThemeEngine { protected: typedef Common::HashMap ImagesMap; @@ -241,6 +271,7 @@ public: kFontStyleFixedItalic = 5, ///< Fixed size italic font. kFontStyleTooltip = 6, ///< Tiny console font kFontStyleConsole = 7, ///< Debug console font + kFontStyleLangExtra = 8, ///< Language specific font for ingame dialogs (e. g. the SCUMM pause/restart dialogs) kFontStyleMax }; @@ -380,6 +411,8 @@ public: return kTextDataTooltip; if (font == kFontStyleConsole) return kTextDataConsole; + if (font == kFontStyleLangExtra) + return kTextDataExtraLang; return kTextDataDefault; } @@ -520,6 +553,22 @@ public: */ bool addFont(TextData textId, const Common::String &language, const Common::String &file, const Common::String &scalableFile, const int pointsize); + /** + * Store language specific font names for ingame GUI dialogs which might require + * a different language than the current GUI setting + * + * @param textId, language, file, scalableFile, pointsize All exactly the same as with addFont() + */ + void storeFontNames(TextData textId, const Common::String &language, const Common::String &file, const Common::String &scalableFile, const int pointsize); + + /** + * Load language specific font for ingame use + * @param style font style associated with the font file + * @param lang language associated with the font file + * @return + */ + bool loadExtraFont(FontStyle style, Common::Language lang); + /** * Interface for the ThemeParser class: adds a text color value. * @@ -741,6 +790,11 @@ protected: /** Array of all font colors available. */ TextColorData *_textColors[kTextColorMAX]; + /** Extra font file names for languages like Japanese, Korean or Chinese + * for use in ingame dialogs (like the SCUMM pause/restart dialogs) + */ + Common::Array _langExtraFonts; + ImagesMap _bitmaps; AImagesMap _abitmaps; Graphics::PixelFormat _overlayFormat; diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp index 020e1091c45..95c70409736 100644 --- a/gui/ThemeParser.cpp +++ b/gui/ThemeParser.cpp @@ -222,6 +222,9 @@ bool ThemeParser::parserCallback_language(ParserNode *node) { scalableFile = getParentNode(node)->values["scalable_file"]; } + + _theme->storeFontNames(textDataId, node->values["id"], file, scalableFile, pointsize); + if (!_theme->addFont(textDataId, node->values["id"], file, scalableFile, pointsize)) return parserError("Error loading localized Font in theme engine."); diff --git a/gui/widget.cpp b/gui/widget.cpp index da2f8406d96..62be5d6061d 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -293,24 +293,22 @@ void Widget::read(const Common::U32String &str) { #pragma mark - -StaticTextWidget::StaticTextWidget(GuiObject *boss, int x, int y, int w, int h, const Common::U32String &text, Graphics::TextAlign align, const Common::U32String &tooltip, ThemeEngine::FontStyle font) +StaticTextWidget::StaticTextWidget(GuiObject *boss, int x, int y, int w, int h, const Common::U32String &text, Graphics::TextAlign align, const Common::U32String &tooltip, ThemeEngine::FontStyle font, Common::Language lang) : Widget(boss, x, y, w, h, tooltip) { setFlags(WIDGET_ENABLED); _type = kStaticTextWidget; _label = text; - _font = font; _align = Graphics::convertTextAlignH(align, g_gui.useRTL() && _useRTL); + setFont(font, lang); } -StaticTextWidget::StaticTextWidget(GuiObject *boss, const Common::String &name, const Common::U32String &text, const Common::U32String &tooltip, ThemeEngine::FontStyle font) +StaticTextWidget::StaticTextWidget(GuiObject *boss, const Common::String &name, const Common::U32String &text, const Common::U32String &tooltip, ThemeEngine::FontStyle font, Common::Language lang) : Widget(boss, name, tooltip) { setFlags(WIDGET_ENABLED | WIDGET_CLEARBG); _type = kStaticTextWidget; _label = text; - _align = Graphics::convertTextAlignH(g_gui.xmlEval()->getWidgetTextHAlign(name), g_gui.useRTL() && _useRTL); - - _font = font; + setFont(font, lang); } void StaticTextWidget::setValue(int value) { @@ -342,6 +340,16 @@ void StaticTextWidget::drawWidget() { ); } +void StaticTextWidget::setFont(ThemeEngine::FontStyle font, Common::Language lang) { + _font = font; + + if (lang == Common::UNK_LANG) + return; + + if (g_gui.theme()->loadExtraFont(font, lang)) + _font = GUI::ThemeEngine::kFontStyleLangExtra; +} + #pragma mark - ButtonWidget::ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Common::U32String &label, const Common::U32String &tooltip, uint32 cmd, uint8 hotkey) diff --git a/gui/widget.h b/gui/widget.h index 9c4810df396..865ec3933b6 100644 --- a/gui/widget.h +++ b/gui/widget.h @@ -200,9 +200,10 @@ protected: Common::U32String _label; Graphics::TextAlign _align; ThemeEngine::FontStyle _font; + public: - StaticTextWidget(GuiObject *boss, int x, int y, int w, int h, const Common::U32String &text, Graphics::TextAlign align, const Common::U32String &tooltip = Common::U32String(""), ThemeEngine::FontStyle font = ThemeEngine::kFontStyleBold); - StaticTextWidget(GuiObject *boss, const Common::String &name, const Common::U32String &text, const Common::U32String &tooltip = Common::U32String(""), ThemeEngine::FontStyle font = ThemeEngine::kFontStyleBold); + StaticTextWidget(GuiObject *boss, int x, int y, int w, int h, const Common::U32String &text, Graphics::TextAlign align, const Common::U32String &tooltip = Common::U32String(""), ThemeEngine::FontStyle font = ThemeEngine::kFontStyleBold, Common::Language lang = Common::UNK_LANG); + StaticTextWidget(GuiObject *boss, const Common::String &name, const Common::U32String &text, const Common::U32String &tooltip = Common::U32String(""), ThemeEngine::FontStyle font = ThemeEngine::kFontStyleBold, Common::Language lang = Common::UNK_LANG); void setValue(int value); void setLabel(const Common::U32String &label); void handleMouseEntered(int button) override { readLabel(); } @@ -213,6 +214,7 @@ public: protected: void drawWidget() override; + void setFont(ThemeEngine::FontStyle font, Common::Language lang); }; /* ButtonWidget */