GUI: allow ingame CJK dialogs regardless of the launcher language
This allows a text widget to be expressly marked as Japanese, Korean or Chinese, so that the theme engine may use an appropriate font.
This commit is contained in:
parent
fb834e55fb
commit
5b6ffeaa3d
7 changed files with 146 additions and 14 deletions
|
@ -382,16 +382,23 @@ void HelpDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 da
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
|
||||||
InfoDialog::InfoDialog(ScummEngine *scumm, int res)
|
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);
|
_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
|
// 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)
|
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;
|
_message = message;
|
||||||
|
|
||||||
|
@ -409,8 +416,8 @@ void InfoDialog::reflowLayout() {
|
||||||
const int screenW = g_system->getOverlayWidth();
|
const int screenW = g_system->getOverlayWidth();
|
||||||
const int screenH = g_system->getOverlayHeight();
|
const int screenH = g_system->getOverlayHeight();
|
||||||
|
|
||||||
int width = g_gui.getStringWidth(_message) + 16;
|
int width = g_gui.getStringWidth(_message, _style) + 16;
|
||||||
int height = g_gui.getFontHeight() + 8;
|
int height = g_gui.getFontHeight(_style) + 8;
|
||||||
|
|
||||||
_w = width;
|
_w = width;
|
||||||
_h = height;
|
_h = height;
|
||||||
|
|
|
@ -72,6 +72,7 @@ protected:
|
||||||
ScummEngine *_vm;
|
ScummEngine *_vm;
|
||||||
U32String _message;
|
U32String _message;
|
||||||
GUI::StaticTextWidget *_text;
|
GUI::StaticTextWidget *_text;
|
||||||
|
GUI::ThemeEngine::FontStyle _style;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// arbitrary message
|
// arbitrary message
|
||||||
|
|
|
@ -553,7 +553,7 @@ bool ThemeEngine::addFont(TextData textId, const Common::String &language, const
|
||||||
Common::String localized = FontMan.genLocalizedFontFilename(file);
|
Common::String localized = FontMan.genLocalizedFontFilename(file);
|
||||||
const Common::String charset
|
const Common::String charset
|
||||||
#ifdef USE_TRANSLATION
|
#ifdef USE_TRANSLATION
|
||||||
(TransMan.getCurrentCharset())
|
(textId == kTextDataExtraLang ? "" : TransMan.getCurrentCharset())
|
||||||
#endif
|
#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<Common::Language> 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<Common::Language> 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<Common::Language> langs = getLangIdentifiers(language);
|
||||||
|
if (langs.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Common::Array<LangExtraFont>::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<LangExtraFont>::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) {
|
bool ThemeEngine::addTextColor(TextColor colorId, int r, int g, int b) {
|
||||||
if (colorId >= kTextColorMAX)
|
if (colorId >= kTextColorMAX)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "common/fs.h"
|
#include "common/fs.h"
|
||||||
#include "common/hash-str.h"
|
#include "common/hash-str.h"
|
||||||
#include "common/hashmap.h"
|
#include "common/hashmap.h"
|
||||||
|
#include "common/language.h"
|
||||||
#include "common/list.h"
|
#include "common/list.h"
|
||||||
#include "common/str.h"
|
#include "common/str.h"
|
||||||
#include "common/rect.h"
|
#include "common/rect.h"
|
||||||
|
@ -151,6 +152,7 @@ enum TextData {
|
||||||
kTextDataNormalFont,
|
kTextDataNormalFont,
|
||||||
kTextDataTooltip,
|
kTextDataTooltip,
|
||||||
kTextDataConsole,
|
kTextDataConsole,
|
||||||
|
kTextDataExtraLang,
|
||||||
kTextDataMAX
|
kTextDataMAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -169,6 +171,34 @@ enum TextColor {
|
||||||
kTextColorMAX
|
kTextColorMAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LangExtraFont {
|
||||||
|
public:
|
||||||
|
LangExtraFont(TextData textId, Common::Array<Common::Language> &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<Common::Language> _langs;
|
||||||
|
Common::String _fontFilesStd[kTextDataMAX];
|
||||||
|
Common::String _fontFilesScalable[kTextDataMAX];
|
||||||
|
int _fontSize[kTextDataMAX];
|
||||||
|
};
|
||||||
|
|
||||||
class ThemeEngine {
|
class ThemeEngine {
|
||||||
protected:
|
protected:
|
||||||
typedef Common::HashMap<Common::String, Graphics::Surface *> ImagesMap;
|
typedef Common::HashMap<Common::String, Graphics::Surface *> ImagesMap;
|
||||||
|
@ -241,6 +271,7 @@ public:
|
||||||
kFontStyleFixedItalic = 5, ///< Fixed size italic font.
|
kFontStyleFixedItalic = 5, ///< Fixed size italic font.
|
||||||
kFontStyleTooltip = 6, ///< Tiny console font
|
kFontStyleTooltip = 6, ///< Tiny console font
|
||||||
kFontStyleConsole = 7, ///< Debug console font
|
kFontStyleConsole = 7, ///< Debug console font
|
||||||
|
kFontStyleLangExtra = 8, ///< Language specific font for ingame dialogs (e. g. the SCUMM pause/restart dialogs)
|
||||||
kFontStyleMax
|
kFontStyleMax
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -380,6 +411,8 @@ public:
|
||||||
return kTextDataTooltip;
|
return kTextDataTooltip;
|
||||||
if (font == kFontStyleConsole)
|
if (font == kFontStyleConsole)
|
||||||
return kTextDataConsole;
|
return kTextDataConsole;
|
||||||
|
if (font == kFontStyleLangExtra)
|
||||||
|
return kTextDataExtraLang;
|
||||||
return kTextDataDefault;
|
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);
|
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.
|
* Interface for the ThemeParser class: adds a text color value.
|
||||||
*
|
*
|
||||||
|
@ -741,6 +790,11 @@ protected:
|
||||||
/** Array of all font colors available. */
|
/** Array of all font colors available. */
|
||||||
TextColorData *_textColors[kTextColorMAX];
|
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<LangExtraFont> _langExtraFonts;
|
||||||
|
|
||||||
ImagesMap _bitmaps;
|
ImagesMap _bitmaps;
|
||||||
AImagesMap _abitmaps;
|
AImagesMap _abitmaps;
|
||||||
Graphics::PixelFormat _overlayFormat;
|
Graphics::PixelFormat _overlayFormat;
|
||||||
|
|
|
@ -222,6 +222,9 @@ bool ThemeParser::parserCallback_language(ParserNode *node) {
|
||||||
scalableFile = getParentNode(node)->values["scalable_file"];
|
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))
|
if (!_theme->addFont(textDataId, node->values["id"], file, scalableFile, pointsize))
|
||||||
return parserError("Error loading localized Font in theme engine.");
|
return parserError("Error loading localized Font in theme engine.");
|
||||||
|
|
||||||
|
|
|
@ -293,24 +293,22 @@ void Widget::read(const Common::U32String &str) {
|
||||||
|
|
||||||
#pragma mark -
|
#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) {
|
: Widget(boss, x, y, w, h, tooltip) {
|
||||||
setFlags(WIDGET_ENABLED);
|
setFlags(WIDGET_ENABLED);
|
||||||
_type = kStaticTextWidget;
|
_type = kStaticTextWidget;
|
||||||
_label = text;
|
_label = text;
|
||||||
_font = font;
|
|
||||||
_align = Graphics::convertTextAlignH(align, g_gui.useRTL() && _useRTL);
|
_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) {
|
: Widget(boss, name, tooltip) {
|
||||||
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
|
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
|
||||||
_type = kStaticTextWidget;
|
_type = kStaticTextWidget;
|
||||||
_label = text;
|
_label = text;
|
||||||
|
|
||||||
_align = Graphics::convertTextAlignH(g_gui.xmlEval()->getWidgetTextHAlign(name), g_gui.useRTL() && _useRTL);
|
_align = Graphics::convertTextAlignH(g_gui.xmlEval()->getWidgetTextHAlign(name), g_gui.useRTL() && _useRTL);
|
||||||
|
setFont(font, lang);
|
||||||
_font = font;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticTextWidget::setValue(int value) {
|
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 -
|
#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)
|
ButtonWidget::ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Common::U32String &label, const Common::U32String &tooltip, uint32 cmd, uint8 hotkey)
|
||||||
|
|
|
@ -200,9 +200,10 @@ protected:
|
||||||
Common::U32String _label;
|
Common::U32String _label;
|
||||||
Graphics::TextAlign _align;
|
Graphics::TextAlign _align;
|
||||||
ThemeEngine::FontStyle _font;
|
ThemeEngine::FontStyle _font;
|
||||||
|
|
||||||
public:
|
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, 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);
|
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 setValue(int value);
|
||||||
void setLabel(const Common::U32String &label);
|
void setLabel(const Common::U32String &label);
|
||||||
void handleMouseEntered(int button) override { readLabel(); }
|
void handleMouseEntered(int button) override { readLabel(); }
|
||||||
|
@ -213,6 +214,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void drawWidget() override;
|
void drawWidget() override;
|
||||||
|
void setFont(ThemeEngine::FontStyle font, Common::Language lang);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ButtonWidget */
|
/* ButtonWidget */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue