From adbaeb7ccada43631f580c504ba01a0f2f6a874a Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 18 Jun 2018 13:43:39 +0400 Subject: [PATCH 1/6] Improve GUI scaling (bug #3288) --- CHANGELOG.md | 1 + apps/openmw/mwbase/windowmanager.hpp | 1 + apps/openmw/mwgui/bookpage.cpp | 45 +++++++------- apps/openmw/mwgui/bookpage.hpp | 46 ++++++++++++++ apps/openmw/mwgui/console.cpp | 6 -- apps/openmw/mwgui/console.hpp | 2 - apps/openmw/mwgui/formatting.cpp | 13 +--- apps/openmw/mwgui/formatting.hpp | 4 +- apps/openmw/mwgui/journalbooks.cpp | 28 ++++++--- apps/openmw/mwgui/journalbooks.hpp | 6 +- apps/openmw/mwgui/journalwindow.cpp | 22 ++++++- apps/openmw/mwgui/merchantrepair.cpp | 11 ++-- apps/openmw/mwgui/merchantrepair.hpp | 2 - apps/openmw/mwgui/review.cpp | 23 +++---- apps/openmw/mwgui/review.hpp | 2 - apps/openmw/mwgui/spellbuyingwindow.cpp | 10 ++-- apps/openmw/mwgui/spellbuyingwindow.hpp | 2 - apps/openmw/mwgui/spellview.cpp | 5 +- apps/openmw/mwgui/statswindow.cpp | 18 +++--- apps/openmw/mwgui/statswindow.hpp | 2 - apps/openmw/mwgui/tooltips.cpp | 7 ++- apps/openmw/mwgui/travelwindow.cpp | 10 ++-- apps/openmw/mwgui/travelwindow.hpp | 2 - apps/openmw/mwgui/windowmanagerimp.cpp | 60 ++++++++++++++++++- apps/openmw/mwgui/windowmanagerimp.hpp | 5 ++ apps/openmw/mwrender/localmap.cpp | 5 ++ components/CMakeLists.txt | 2 +- components/widgets/box.cpp | 9 +-- components/widgets/box.hpp | 26 +++++++- components/widgets/fontwrapper.hpp | 45 ++++++++++++++ components/widgets/numericeditbox.hpp | 7 ++- components/widgets/sharedstatebutton.cpp | 1 - components/widgets/sharedstatebutton.hpp | 4 +- components/widgets/widgets.cpp | 3 + components/widgets/widgets.hpp | 3 +- .../source/reference/modding/settings/GUI.rst | 21 +++++++ files/mygui/core.skin | 1 - files/mygui/openmw_confirmation_dialog.layout | 2 +- files/mygui/openmw_enchanting_dialog.layout | 2 +- files/mygui/openmw_font.xml | 2 - files/mygui/openmw_inventory_window.layout | 2 +- files/mygui/openmw_journal.layout | 5 +- files/mygui/openmw_journal.skin.xml | 6 +- files/mygui/openmw_list.skin.xml | 4 -- files/mygui/openmw_windows.skin.xml | 8 +-- files/settings-default.cfg | 6 ++ 46 files changed, 352 insertions(+), 145 deletions(-) create mode 100644 components/widgets/fontwrapper.hpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 44cb90afd..37bf5e660 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ Bug #3059: Unable to hit with marksman weapons when too close to an enemy Bug #3072: Fatal error on AddItem that has a script containing Equip Bug #3249: Fixed revert function not updating views properly + Bug #3288: TrueType fonts are handled incorrectly Bug #3374: Touch spells not hitting kwama foragers Bug #3486: [Mod] NPC Commands does not work Bug #3533: GetSpellEffects should detect effects with zero duration diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 39eed5537..b40f517f9 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -219,6 +219,7 @@ namespace MWBase virtual const MWWorld::Ptr& getSelectedEnchantItem() const = 0; virtual void setSelectedWeapon(const MWWorld::Ptr& item) = 0; virtual const MWWorld::Ptr& getSelectedWeapon() const = 0; + virtual int getFontHeight() const = 0; virtual void unsetSelectedSpell() = 0; virtual void unsetSelectedWeapon() = 0; diff --git a/apps/openmw/mwgui/bookpage.cpp b/apps/openmw/mwgui/bookpage.cpp index 6f16cf076..8f2e8b5ed 100644 --- a/apps/openmw/mwgui/bookpage.cpp +++ b/apps/openmw/mwgui/bookpage.cpp @@ -1,6 +1,5 @@ #include "bookpage.hpp" -#include "MyGUI_FontManager.h" #include "MyGUI_RenderItem.h" #include "MyGUI_RenderManager.h" #include "MyGUI_TextureUtility.h" @@ -8,6 +7,9 @@ #include +#include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" + namespace MWGui { struct TypesetBookImpl; @@ -497,9 +499,9 @@ struct TypesetBookImpl::Typesetter : BookTypesetter while (!stream.eof () && !ucsLineBreak (stream.peek ()) && ucsBreakingSpace (stream.peek ())) { - MyGUI::GlyphInfo* gi = style->mFont->getGlyphInfo (stream.peek ()); - if (gi) - space_width += static_cast(gi->advance + gi->bearingX); + MWGui::GlyphInfo info = GlyphInfo(style->mFont, stream.peek()); + if (info.codePoint >= 0) + space_width += static_cast(info.advance + info.bearingX); stream.consume (); } @@ -507,9 +509,9 @@ struct TypesetBookImpl::Typesetter : BookTypesetter while (!stream.eof () && !ucsLineBreak (stream.peek ()) && !ucsBreakingSpace (stream.peek ())) { - MyGUI::GlyphInfo* gi = style->mFont->getGlyphInfo (stream.peek ()); - if (gi) - word_width += static_cast(gi->advance + gi->bearingX); + MWGui::GlyphInfo info = GlyphInfo(style->mFont, stream.peek()); + if (info.codePoint >= 0) + word_width += static_cast(info.advance + info.bearingX); stream.consume (); } @@ -530,6 +532,7 @@ struct TypesetBookImpl::Typesetter : BookTypesetter if (mPartialWhitespace.empty() && mPartialWord.empty()) return; + int fontHeight = MWBase::Environment::get().getWindowManager()->getFontHeight(); int space_width = 0; int word_width = 0; @@ -549,9 +552,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter for (PartialTextConstIterator i = mPartialWhitespace.begin (); i != mPartialWhitespace.end (); ++i) { int top = mLine ? mLine->mRect.top : mBook->mRect.bottom; - int line_height = i->mStyle->mFont->getDefaultHeight (); - append_run ( i->mStyle, i->mBegin, i->mEnd, 0, left + i->mWidth, top + line_height); + append_run ( i->mStyle, i->mBegin, i->mEnd, 0, left + i->mWidth, top + fontHeight); left = mLine->mRect.right; } @@ -560,9 +562,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter for (PartialTextConstIterator i = mPartialWord.begin (); i != mPartialWord.end (); ++i) { int top = mLine ? mLine->mRect.top : mBook->mRect.bottom; - int line_height = i->mStyle->mFont->getDefaultHeight (); - append_run (i->mStyle, i->mBegin, i->mEnd, i->mEnd - i->mBegin, left + i->mWidth, top + line_height); + append_run (i->mStyle, i->mBegin, i->mEnd, i->mEnd - i->mBegin, left + i->mWidth, top + fontHeight); left = mLine->mRect.right; } @@ -756,32 +757,32 @@ namespace void emitGlyph (wchar_t ch) { - MyGUI::GlyphInfo* gi = mFont->getGlyphInfo (ch); + MWGui::GlyphInfo info = GlyphInfo(mFont, ch); - if (!gi) + if (info.codePoint < 0) return; MyGUI::FloatRect vr; - vr.left = mCursor.left + gi->bearingX; - vr.top = mCursor.top + gi->bearingY; - vr.right = vr.left + gi->width; - vr.bottom = vr.top + gi->height; + vr.left = mCursor.left + info.bearingX; + vr.top = mCursor.top + info.bearingY; + vr.right = vr.left + info.width; + vr.bottom = vr.top + info.height; - MyGUI::FloatRect tr = gi->uvRect; + MyGUI::FloatRect tr = info.uvRect; if (mRenderXform.clip (vr, tr)) quad (vr, tr); - mCursor.left += gi->bearingX + gi->advance; + mCursor.left += static_cast(info.bearingX + info.advance); } void emitSpace (wchar_t ch) { - MyGUI::GlyphInfo* gi = mFont->getGlyphInfo (ch); + MWGui::GlyphInfo info = GlyphInfo(mFont, ch); - if (gi) - mCursor.left += gi->bearingX + gi->advance; + if (info.codePoint >= 0) + mCursor.left += static_cast(info.bearingX + info.advance); } private: diff --git a/apps/openmw/mwgui/bookpage.hpp b/apps/openmw/mwgui/bookpage.hpp index 66d1834c7..b8174bd3d 100644 --- a/apps/openmw/mwgui/bookpage.hpp +++ b/apps/openmw/mwgui/bookpage.hpp @@ -3,10 +3,17 @@ #include "MyGUI_Colour.h" #include "MyGUI_Widget.h" +#include "MyGUI_FontManager.h" #include #include +#include +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" + namespace MWGui { /// A formatted and paginated document to be used with @@ -28,6 +35,45 @@ namespace MWGui virtual std::pair getSize () const = 0; }; + struct GlyphInfo + { + char codePoint; + float width; + float height; + float advance; + float bearingX; + float bearingY; + MyGUI::FloatRect uvRect; + + GlyphInfo(MyGUI::IFont* font, MyGUI::Char ch) + { + static const int fontHeight = MWBase::Environment::get().getWindowManager()->getFontHeight(); + + MyGUI::GlyphInfo* gi = font->getGlyphInfo(ch); + if (gi) + { + const float scale = font->getDefaultHeight() / (float) fontHeight; + + codePoint = gi->codePoint; + bearingX = (int) gi->bearingX / scale; + bearingY = (int) gi->bearingY / scale; + width = (int) gi->width / scale; + height = (int) gi->height / scale; + advance = (int) gi->advance / scale; + uvRect = gi->uvRect; + } + else + { + codePoint = -1; + bearingX = 0; + bearingY = 0; + width = 0; + height = 0; + advance = 0; + } + } + }; + /// A factory class for creating a typeset book instance. struct BookTypesetter { diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index b367c6f49..dc22e4193 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -152,12 +152,6 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCommandLine); } - void Console::setFont(const std::string &fntName) - { - mHistory->setFontName(fntName); - mCommandLine->setFontName(fntName); - } - void Console::print(const std::string &msg, const std::string& color) { mHistory->addText(color + MyGUI::TextIterator::toTagsString(msg)); diff --git a/apps/openmw/mwgui/console.hpp b/apps/openmw/mwgui/console.hpp index bbff34c8d..883bc8967 100644 --- a/apps/openmw/mwgui/console.hpp +++ b/apps/openmw/mwgui/console.hpp @@ -41,8 +41,6 @@ namespace MWGui virtual void onOpen(); - void setFont(const std::string &fntName); - void onResChange(int width, int height); // Print a message to the console, in specified color. diff --git a/apps/openmw/mwgui/formatting.cpp b/apps/openmw/mwgui/formatting.cpp index 663bd7338..157aeba26 100644 --- a/apps/openmw/mwgui/formatting.cpp +++ b/apps/openmw/mwgui/formatting.cpp @@ -415,7 +415,7 @@ namespace MWGui : GraphicElement(parent, pag, blockStyle), mTextStyle(textStyle) { - MyGUI::EditBox* box = parent->createWidget("NormalText", + Gui::EditBox* box = parent->createWidget("NormalText", MyGUI::IntCoord(0, pag.getCurrentTop(), pag.getPageWidth(), 0), MyGUI::Align::Left | MyGUI::Align::Top, parent->getName() + MyGUI::utility::toString(parent->getChildCount())); box->setEditStatic(true); @@ -432,15 +432,6 @@ namespace MWGui mEditBox = box; } - int TextElement::currentFontHeight() const - { - std::string fontName(mTextStyle.mFont == "Default" ? MyGUI::FontManager::getInstance().getDefaultFont() : mTextStyle.mFont); - MyGUI::IFont* font = MyGUI::FontManager::getInstance().getByName(fontName); - if (!font) - return 0; - return font->getDefaultHeight(); - } - int TextElement::getHeight() { return mEditBox->getTextSize().height; @@ -449,7 +440,7 @@ namespace MWGui int TextElement::pageSplit() { // split lines - const int lineHeight = currentFontHeight(); + const int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight(); unsigned int lastLine = (mPaginator.getStartTop() + mPaginator.getPageHeight() - mPaginator.getCurrentTop()); if (lineHeight > 0) lastLine /= lineHeight; diff --git a/apps/openmw/mwgui/formatting.hpp b/apps/openmw/mwgui/formatting.hpp index d525baace..7ccb0824e 100644 --- a/apps/openmw/mwgui/formatting.hpp +++ b/apps/openmw/mwgui/formatting.hpp @@ -4,6 +4,8 @@ #include #include +#include + namespace MWGui { namespace Formatting @@ -152,7 +154,7 @@ namespace MWGui private: int currentFontHeight() const; TextStyle mTextStyle; - MyGUI::EditBox * mEditBox; + Gui::EditBox * mEditBox; }; class ImageElement : public GraphicElement diff --git a/apps/openmw/mwgui/journalbooks.cpp b/apps/openmw/mwgui/journalbooks.cpp index 1075239fa..1956ee1c2 100644 --- a/apps/openmw/mwgui/journalbooks.cpp +++ b/apps/openmw/mwgui/journalbooks.cpp @@ -218,21 +218,24 @@ book JournalBooks::createQuestBook (const std::string& questName) return typesetter->complete (); } -book JournalBooks::createTopicIndexBook () +book JournalBooks::createTopicIndexBook (int& columnsCount) { bool isRussian = (mEncoding == ToUTF8::WINDOWS_1251); - BookTypesetter::Ptr typesetter = isRussian ? createCyrillicJournalIndex() : createLatinJournalIndex(); + BookTypesetter::Ptr typesetter = isRussian ? createCyrillicJournalIndex(columnsCount) : createLatinJournalIndex(columnsCount); return typesetter->complete (); } -BookTypesetter::Ptr JournalBooks::createLatinJournalIndex () +BookTypesetter::Ptr JournalBooks::createLatinJournalIndex (int& columnsCount) { - BookTypesetter::Ptr typesetter = BookTypesetter::create (92, 250); + BookTypesetter::Ptr typesetter = BookTypesetter::create (92, 260); typesetter->setSectionAlignment (BookTypesetter::AlignCenter); + // Latin journal index always has two columns for now. + columnsCount = 2; + char ch = 'A'; BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); @@ -258,14 +261,25 @@ BookTypesetter::Ptr JournalBooks::createLatinJournalIndex () return typesetter; } -BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex () +BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex (int& columnsCount) { - BookTypesetter::Ptr typesetter = BookTypesetter::create (92, 250); + BookTypesetter::Ptr typesetter = BookTypesetter::create (92, 260); typesetter->setSectionAlignment (BookTypesetter::AlignCenter); BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); + int fontHeight = MWBase::Environment::get().getWindowManager()->getFontHeight(); + + // for small font size split alphabet to two columns (2x15 characers), for big font size split it to three colums (3x10 characters). + int sectionBreak = 10; + columnsCount = 3; + if (fontHeight < 18) + { + sectionBreak = 15; + columnsCount = 2; + } + unsigned char ch[2] = {0xd0, 0x90}; // CYRILLIC CAPITAL A is a 0xd090 in UTF-8 for (int i = 0; i < 32; ++i) @@ -287,7 +301,7 @@ BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex () if (i == 26 || i == 28) continue; - if (i == 15) + if (i % sectionBreak == 0) typesetter->sectionBreak (); typesetter->write (style, to_utf8_span (buffer)); diff --git a/apps/openmw/mwgui/journalbooks.hpp b/apps/openmw/mwgui/journalbooks.hpp index aa36eecdf..cc6f42cc8 100644 --- a/apps/openmw/mwgui/journalbooks.hpp +++ b/apps/openmw/mwgui/journalbooks.hpp @@ -22,14 +22,14 @@ namespace MWGui Book createTopicBook (uintptr_t topicId); Book createTopicBook (const std::string& topicId); Book createQuestBook (const std::string& questName); - Book createTopicIndexBook (); + Book createTopicIndexBook (int& columnsCount); ToUTF8::FromType mEncoding; private: BookTypesetter::Ptr createTypesetter (); - BookTypesetter::Ptr createLatinJournalIndex (); - BookTypesetter::Ptr createCyrillicJournalIndex (); + BookTypesetter::Ptr createLatinJournalIndex (int& columnsCount); + BookTypesetter::Ptr createCyrillicJournalIndex (int& columnsCount); }; } diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index 0776706d8..cef20159d 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -43,6 +43,7 @@ namespace static char const LeftBookPage [] = "LeftBookPage"; static char const RightBookPage [] = "RightBookPage"; static char const LeftTopicIndex [] = "LeftTopicIndex"; + static char const CenterTopicIndex [] = "CenterTopicIndex"; static char const RightTopicIndex [] = "RightTopicIndex"; struct JournalWindowImpl : MWGui::JournalBooks, MWGui::JournalWindow @@ -148,6 +149,7 @@ namespace callback = std::bind(&JournalWindowImpl::notifyIndexLinkClicked, this, std::placeholders::_1); getPage (LeftTopicIndex)->adviseLinkClicked (callback); + getPage (CenterTopicIndex)->adviseLinkClicked (callback); getPage (RightTopicIndex)->adviseLinkClicked (callback); } @@ -312,6 +314,7 @@ namespace setVisible (TopicsList, false); setVisible (QuestsList, mQuestMode); setVisible (LeftTopicIndex, !mQuestMode); + setVisible (CenterTopicIndex, !mQuestMode); setVisible (RightTopicIndex, !mQuestMode); setVisible (ShowAllBTN, mQuestMode && !mAllQuests); setVisible (ShowActiveBTN, mQuestMode && mAllQuests); @@ -462,11 +465,21 @@ namespace { setOptionsMode (); + int pagesCount; if (!mTopicIndexBook) - mTopicIndexBook = createTopicIndexBook (); + mTopicIndexBook = createTopicIndexBook (pagesCount); - getPage (LeftTopicIndex)->showPage (mTopicIndexBook, 0); - getPage (RightTopicIndex)->showPage (mTopicIndexBook, 1); + if (pagesCount == 3) + { + getPage (LeftTopicIndex)->showPage (mTopicIndexBook, 0); + getPage (CenterTopicIndex)->showPage (mTopicIndexBook, 1); + getPage (RightTopicIndex)->showPage (mTopicIndexBook, 2); + } + else + { + getPage (LeftTopicIndex)->showPage (mTopicIndexBook, 0); + getPage (RightTopicIndex)->showPage (mTopicIndexBook, 1); + } } void notifyJournal(MyGUI::Widget* _sender) @@ -480,6 +493,7 @@ namespace void notifyIndexLinkClicked (MWGui::TypesetBook::InteractiveId index) { setVisible (LeftTopicIndex, false); + setVisible (CenterTopicIndex, false); setVisible (RightTopicIndex, false); setVisible (TopicsList, true); @@ -502,6 +516,7 @@ namespace mQuestMode = false; mTopicsMode = false; setVisible (LeftTopicIndex, true); + setVisible (CenterTopicIndex, true); setVisible (RightTopicIndex, true); setVisible (TopicsList, false); setVisible (QuestsList, false); @@ -540,6 +555,7 @@ namespace mQuestMode = true; setVisible (LeftTopicIndex, false); + setVisible (CenterTopicIndex, true); setVisible (RightTopicIndex, false); setVisible (TopicsList, false); setVisible (QuestsList, true); diff --git a/apps/openmw/mwgui/merchantrepair.cpp b/apps/openmw/mwgui/merchantrepair.cpp index 9974c6d16..b9d4c80f4 100644 --- a/apps/openmw/mwgui/merchantrepair.cpp +++ b/apps/openmw/mwgui/merchantrepair.cpp @@ -20,8 +20,6 @@ namespace MWGui { -const int MerchantRepair::sLineHeight = 18; - MerchantRepair::MerchantRepair() : WindowBase("openmw_merchantrepair.layout") { @@ -39,6 +37,7 @@ void MerchantRepair::setPtr(const MWWorld::Ptr &actor) while (mList->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(mList->getChildAt(0)); + int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; int currentY = 0; MWWorld::Ptr player = MWMechanics::getPlayer(); @@ -67,28 +66,26 @@ void MerchantRepair::setPtr(const MWWorld::Ptr &actor) int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mActor, x, true); - std::string name = iter->getClass().getName(*iter) + " - " + MyGUI::utility::toString(price) + MWBase::Environment::get().getWorld()->getStore().get() .find("sgp")->mValue.getString(); - MyGUI::Button* button = mList->createWidget(price <= playerGold ? "SandTextButton" : "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip 0, currentY, 0, - sLineHeight, + lineHeight, MyGUI::Align::Default ); - currentY += sLineHeight; + currentY += lineHeight; button->setUserString("Price", MyGUI::utility::toString(price)); button->setUserData(MWWorld::Ptr(*iter)); button->setCaptionWithReplacing(name); - button->setSize(mList->getWidth(),sLineHeight); + button->setSize(mList->getWidth(), lineHeight); button->eventMouseWheel += MyGUI::newDelegate(this, &MerchantRepair::onMouseWheel); button->setUserString("ToolTipType", "ItemPtr"); button->eventMouseButtonClick += MyGUI::newDelegate(this, &MerchantRepair::onRepairButtonClick); diff --git a/apps/openmw/mwgui/merchantrepair.hpp b/apps/openmw/mwgui/merchantrepair.hpp index 4e4e7164f..26887ae2c 100644 --- a/apps/openmw/mwgui/merchantrepair.hpp +++ b/apps/openmw/mwgui/merchantrepair.hpp @@ -27,8 +27,6 @@ protected: void onMouseWheel(MyGUI::Widget* _sender, int _rel); void onRepairButtonClick(MyGUI::Widget* sender); void onOkButtonClick(MyGUI::Widget* sender); - - static const int sLineHeight; }; } diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index 61a7a2ac0..b59b1582c 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -26,9 +26,6 @@ namespace namespace MWGui { - - const int ReviewDialog::sLineHeight = 18; - ReviewDialog::ReviewDialog() : WindowModal("openmw_chargen_review.layout"), mUpdateSkillArea(false) @@ -261,8 +258,9 @@ namespace MWGui groupWidget->setCaption(label); mSkillWidgets.push_back(groupWidget); - coord1.top += sLineHeight; - coord2.top += sLineHeight; + int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; + coord1.top += lineHeight; + coord2.top += lineHeight; } MyGUI::TextBox* ReviewDialog::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) @@ -282,8 +280,9 @@ namespace MWGui mSkillWidgets.push_back(skillNameWidget); mSkillWidgets.push_back(skillValueWidget); - coord1.top += sLineHeight; - coord2.top += sLineHeight; + int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; + coord1.top += lineHeight; + coord2.top += lineHeight; return skillValueWidget; } @@ -298,8 +297,9 @@ namespace MWGui mSkillWidgets.push_back(skillNameWidget); - coord1.top += sLineHeight; - coord2.top += sLineHeight; + int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; + coord1.top += lineHeight; + coord2.top += lineHeight; } void ReviewDialog::addItem(const ESM::Spell* spell, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) @@ -312,8 +312,9 @@ namespace MWGui mSkillWidgets.push_back(widget); - coord1.top += sLineHeight; - coord2.top += sLineHeight; + int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; + coord1.top += lineHeight; + coord2.top += lineHeight; } void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) diff --git a/apps/openmw/mwgui/review.hpp b/apps/openmw/mwgui/review.hpp index 8e9ec0ec7..f46ad280d 100644 --- a/apps/openmw/mwgui/review.hpp +++ b/apps/openmw/mwgui/review.hpp @@ -87,8 +87,6 @@ namespace MWGui void addItem(const ESM::Spell* spell, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); void updateSkillArea(); - static const int sLineHeight; - MyGUI::TextBox *mNameWidget, *mRaceWidget, *mClassWidget, *mBirthSignWidget; MyGUI::ScrollView* mSkillView; diff --git a/apps/openmw/mwgui/spellbuyingwindow.cpp b/apps/openmw/mwgui/spellbuyingwindow.cpp index 9876013f1..bc5d161d8 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.cpp +++ b/apps/openmw/mwgui/spellbuyingwindow.cpp @@ -18,8 +18,6 @@ namespace MWGui { - const int SpellBuyingWindow::sLineHeight = 18; - SpellBuyingWindow::SpellBuyingWindow() : WindowBase("openmw_spell_buying_window.layout") , mCurrentY(0) @@ -52,21 +50,23 @@ namespace MWGui // TODO: refactor to use MyGUI::ListBox + int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; + MyGUI::Button* toAdd = mSpellsView->createWidget( price <= playerGold ? "SandTextButton" : "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip 0, mCurrentY, 200, - sLineHeight, + lineHeight, MyGUI::Align::Default ); - mCurrentY += sLineHeight; + mCurrentY += lineHeight; toAdd->setUserData(price); toAdd->setCaptionWithReplacing(spell.mName+" - "+MyGUI::utility::toString(price)+"#{sgp}"); - toAdd->setSize(mSpellsView->getWidth(),sLineHeight); + toAdd->setSize(mSpellsView->getWidth(), lineHeight); toAdd->eventMouseWheel += MyGUI::newDelegate(this, &SpellBuyingWindow::onMouseWheel); toAdd->setUserString("ToolTipType", "Spell"); toAdd->setUserString("Spell", spell.mId); diff --git a/apps/openmw/mwgui/spellbuyingwindow.hpp b/apps/openmw/mwgui/spellbuyingwindow.hpp index 3414c1b94..30727a545 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.hpp +++ b/apps/openmw/mwgui/spellbuyingwindow.hpp @@ -48,8 +48,6 @@ namespace MWGui void clearSpells(); int mCurrentY; - static const int sLineHeight; - void updateLabels(); virtual void onReferenceUnavailable(); diff --git a/apps/openmw/mwgui/spellview.cpp b/apps/openmw/mwgui/spellview.cpp index 758e6b306..702c2f840 100644 --- a/apps/openmw/mwgui/spellview.cpp +++ b/apps/openmw/mwgui/spellview.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "tooltips.hpp" @@ -240,7 +241,7 @@ namespace MWGui mLines.push_back(LineInfo(separator, (MyGUI::Widget*)NULL, NoSpellIndex)); } - MyGUI::TextBox* groupWidget = mScrollView->createWidget("SandBrightText", + MyGUI::TextBox* groupWidget = mScrollView->createWidget("SandBrightText", MyGUI::IntCoord(0, 0, mScrollView->getWidth(), 24), MyGUI::Align::Left | MyGUI::Align::Top); groupWidget->setCaptionWithReplacing(label); @@ -249,7 +250,7 @@ namespace MWGui if (label2 != "") { - MyGUI::TextBox* groupWidget2 = mScrollView->createWidget("SandBrightText", + MyGUI::TextBox* groupWidget2 = mScrollView->createWidget("SandBrightText", MyGUI::IntCoord(0, 0, mScrollView->getWidth(), 24), MyGUI::Align::Left | MyGUI::Align::Top); groupWidget2->setCaptionWithReplacing(label2); diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index db73351bf..dfa029467 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -23,9 +23,6 @@ namespace MWGui { - - const int StatsWindow::sLineHeight = 18; - StatsWindow::StatsWindow (DragAndDrop* drag) : WindowPinnableBase("openmw_stats_window.layout") , NoDrop(drag, mMainWidget) @@ -376,8 +373,9 @@ namespace MWGui groupWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel); mSkillWidgets.push_back(groupWidget); - coord1.top += sLineHeight; - coord2.top += sLineHeight; + int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; + coord1.top += lineHeight; + coord2.top += lineHeight; } std::pair StatsWindow::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) @@ -401,8 +399,9 @@ namespace MWGui mSkillWidgets.push_back(skillNameWidget); mSkillWidgets.push_back(skillValueWidget); - coord1.top += sLineHeight; - coord2.top += sLineHeight; + int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; + coord1.top += lineHeight; + coord2.top += lineHeight; return std::make_pair(skillNameWidget, skillValueWidget); } @@ -421,8 +420,9 @@ namespace MWGui mSkillWidgets.push_back(skillNameWidget); - coord1.top += sLineHeight; - coord2.top += sLineHeight; + int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; + coord1.top += lineHeight; + coord2.top += lineHeight; return skillNameWidget; } diff --git a/apps/openmw/mwgui/statswindow.hpp b/apps/openmw/mwgui/statswindow.hpp index 487953e00..8dab2f3d9 100644 --- a/apps/openmw/mwgui/statswindow.hpp +++ b/apps/openmw/mwgui/statswindow.hpp @@ -53,8 +53,6 @@ namespace MWGui void onWindowResize(MyGUI::Window* window); void onMouseWheel(MyGUI::Widget* _sender, int _rel); - static const int sLineHeight; - MyGUI::Widget* mLeftPane; MyGUI::Widget* mRightPane; diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 20814aac5..0bd0d191c 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -8,6 +8,7 @@ #include #include +#include #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" @@ -421,7 +422,7 @@ namespace MWGui std::string realImage = MWBase::Environment::get().getWindowManager()->correctIconPath(image); - MyGUI::EditBox* captionWidget = mDynamicToolTipBox->createWidget("NormalText", MyGUI::IntCoord(0, 0, 300, 300), MyGUI::Align::Left | MyGUI::Align::Top, "ToolTipCaption"); + Gui::EditBox* captionWidget = mDynamicToolTipBox->createWidget("NormalText", MyGUI::IntCoord(0, 0, 300, 300), MyGUI::Align::Left | MyGUI::Align::Top, "ToolTipCaption"); captionWidget->setEditStatic(true); captionWidget->setNeedKeyFocus(false); captionWidget->setCaptionWithReplacing(caption); @@ -429,7 +430,7 @@ namespace MWGui int captionHeight = std::max(caption != "" ? captionSize.height : 0, imageSize); - MyGUI::EditBox* textWidget = mDynamicToolTipBox->createWidget("SandText", MyGUI::IntCoord(0, captionHeight+imageCaptionVPadding, 300, 300-captionHeight-imageCaptionVPadding), MyGUI::Align::Stretch, "ToolTipText"); + Gui::EditBox* textWidget = mDynamicToolTipBox->createWidget("SandText", MyGUI::IntCoord(0, captionHeight+imageCaptionVPadding, 300, 300-captionHeight-imageCaptionVPadding), MyGUI::Align::Stretch, "ToolTipText"); textWidget->setEditStatic(true); textWidget->setEditMultiLine(true); textWidget->setEditWordWrap(info.wordWrap); @@ -447,7 +448,7 @@ namespace MWGui MyGUI::ImageBox* icon = mDynamicToolTipBox->createWidget("MarkerButton", MyGUI::IntCoord(padding.left, totalSize.height+padding.top, 8, 8), MyGUI::Align::Default); icon->setColour(MyGUI::Colour(1.0f, 0.3f, 0.3f)); - MyGUI::EditBox* edit = mDynamicToolTipBox->createWidget("SandText", + Gui::EditBox* edit = mDynamicToolTipBox->createWidget("SandText", MyGUI::IntCoord(padding.left+8+4, totalSize.height+padding.top, 300-padding.left-8-4, 300-totalSize.height), MyGUI::Align::Default); edit->setEditMultiLine(true); diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 23a5b322f..5f5430524 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -22,8 +22,6 @@ namespace MWGui { - const int TravelWindow::sLineHeight = 18; - TravelWindow::TravelWindow() : WindowBase("openmw_travel_window.layout") , mCurrentY(0) @@ -79,9 +77,11 @@ namespace MWGui else price *= std::max(1, static_cast(followers.size())); - MyGUI::Button* toAdd = mDestinationsView->createWidget("SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); + int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; + + MyGUI::Button* toAdd = mDestinationsView->createWidget("SandTextButton", 0, mCurrentY, 200, lineHeight, MyGUI::Align::Default); toAdd->setEnabled(price <= playerGold); - mCurrentY += sLineHeight; + mCurrentY += lineHeight; if(interior) toAdd->setUserString("interior","y"); else @@ -92,7 +92,7 @@ namespace MWGui toAdd->setUserString("price",oss.str()); toAdd->setCaptionWithReplacing("#{sCell=" + name + "} - " + MyGUI::utility::toString(price)+"#{sgp}"); - toAdd->setSize(mDestinationsView->getWidth(),sLineHeight); + toAdd->setSize(mDestinationsView->getWidth(),lineHeight); toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel); toAdd->setUserString("Destination", name); toAdd->setUserData(pos); diff --git a/apps/openmw/mwgui/travelwindow.hpp b/apps/openmw/mwgui/travelwindow.hpp index 5ae466047..dcf0b7727 100644 --- a/apps/openmw/mwgui/travelwindow.hpp +++ b/apps/openmw/mwgui/travelwindow.hpp @@ -41,8 +41,6 @@ namespace MWGui void clearDestinations(); int mCurrentY; - static const int sLineHeight; - void updateLabels(); virtual void onReferenceUnavailable(); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 6917e2e8a..493a14a1c 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -44,7 +44,6 @@ #include -#include #include #include @@ -196,6 +195,7 @@ namespace MWGui , mFallbackMap(fallbackMap) , mShowOwned(0) , mEncoding(encoding) + , mFontHeight(16) , mVersionDescription(versionDescription) { float uiScale = Settings::Manager::getFloat("scaling factor", "GUI"); @@ -233,6 +233,13 @@ namespace MWGui SpellView::registerComponents(); Gui::registerAllWidgets(); + int fontSize = Settings::Manager::getInt("font size", "GUI"); + fontSize = std::min(std::max(12, fontSize), 20); + mFontHeight = fontSize; + + MyGUI::ResourceManager::getInstance().unregisterLoadXmlDelegate("Resource"); + MyGUI::ResourceManager::getInstance().registerLoadXmlDelegate("Resource") = newDelegate(this, &WindowManager::loadFontDelegate); + MyGUI::FactoryManager::getInstance().registerFactory("Controller"); MyGUI::FactoryManager::getInstance().registerFactory("Controller"); @@ -284,6 +291,51 @@ namespace MWGui mShowOwned = Settings::Manager::getInt("show owned", "Game"); } + void WindowManager::loadFontDelegate(MyGUI::xml::ElementPtr _node, const std::string& _file, MyGUI::Version _version) + { + MyGUI::xml::ElementEnumerator root = _node->getElementEnumerator(); + while (root.next("Resource")) + { + std::string type, name; + root->findAttribute("type", type); + root->findAttribute("name", name); + + if (name.empty()) + continue; + + if (Misc::StringUtils::ciEqual(type, "ResourceTrueTypeFont")) + { + // For TrueType fonts we should override Size and Resolution properties + // to allow to configure font size via config file, without need to edit XML file. + // Also we should take UI scaling factor in account + int resolution = Settings::Manager::getInt("ttf resolution", "GUI"); + resolution = std::max(0, resolution); + + float uiScale = Settings::Manager::getFloat("scaling factor", "GUI"); + + if (uiScale > 1.0f) + resolution *= uiScale; + + MyGUI::xml::ElementPtr resolutionNode = root->createChild("Property"); + resolutionNode->addAttribute("key", "Resolution"); + resolutionNode->addAttribute("value", std::to_string(resolution)); + + MyGUI::xml::ElementPtr sizeNode = root->createChild("Property"); + sizeNode->addAttribute("key", "Size"); + sizeNode->addAttribute("value", std::to_string(mFontHeight)); + } + else if (Misc::StringUtils::ciEqual(type, "ResourceSkin")) + { + // We should adjust line height for MyGUI widgets depending on font size + MyGUI::xml::ElementPtr heightNode = root->createChild("Property"); + heightNode->addAttribute("key", "HeightLine"); + heightNode->addAttribute("value", std::to_string(mFontHeight+2)); + } + } + + MyGUI::ResourceManager::getInstance().loadFromXmlNode(_node, _file, _version); + } + void WindowManager::initUI() { // Get size info from the Gui object @@ -504,6 +556,11 @@ namespace MWGui updateVisible(); } + int WindowManager::getFontHeight() const + { + return mFontHeight; + } + void WindowManager::setNewGame(bool newgame) { if (newgame) @@ -522,6 +579,7 @@ namespace MWGui { mKeyboardNavigation.reset(); + MyGUI::ResourceManager::getInstance().unregisterLoadXmlDelegate("Resource"); MyGUI::LanguageManager::getInstance().eventRequestTag.clear(); MyGUI::PointerManager::getInstance().eventChangeMousePointer.clear(); MyGUI::InputManager::getInstance().eventChangeKeyFocus.clear(); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 657548397..f3bf6d00f 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -246,6 +246,7 @@ namespace MWGui virtual const MWWorld::Ptr& getSelectedEnchantItem() const; virtual void setSelectedWeapon(const MWWorld::Ptr& item); virtual const MWWorld::Ptr& getSelectedWeapon() const; + virtual int getFontHeight() const; virtual void unsetSelectedSpell(); virtual void unsetSelectedWeapon(); @@ -401,6 +402,8 @@ namespace MWGui MWWorld::Ptr mSelectedEnchantItem; MWWorld::Ptr mSelectedWeapon; + void loadFontDelegate(MyGUI::xml::ElementPtr _node, const std::string& _file, MyGUI::Version _version); + std::vector mCurrentModals; // Markers placed manually by the player. Must be shared between both map views (the HUD map and the map window). @@ -513,6 +516,8 @@ namespace MWGui ToUTF8::FromType mEncoding; + int mFontHeight; + std::string mVersionDescription; MWGui::TextColours mTextColours; diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 5e501ecf8..8ed3441de 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -76,6 +76,11 @@ LocalMap::LocalMap(osg::Group* root) , mAngle(0.f) , mInterior(false) { + // Increase map resolution, if use UI scaling + float uiScale = Settings::Manager::getFloat("scaling factor", "GUI"); + if (uiScale > 1.0) + mMapResolution *= uiScale; + SceneUtil::FindByNameVisitor find("Scene Root"); mRoot->accept(find); mSceneRoot = find.mFoundNode; diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 551767f8f..8e798455f 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -130,7 +130,7 @@ add_component_dir (myguiplatform ) add_component_dir (widgets - box imagebutton tags list numericeditbox sharedstatebutton windowcaption widgets + box fontwrapper imagebutton tags list numericeditbox sharedstatebutton windowcaption widgets ) add_component_dir (fontloader diff --git a/components/widgets/box.cpp b/components/widgets/box.cpp index bf18cef5b..d38410a2c 100644 --- a/components/widgets/box.cpp +++ b/components/widgets/box.cpp @@ -48,7 +48,7 @@ namespace Gui } else { - TextBox::setPropertyOverride (_key, _value); + Gui::TextBox::setPropertyOverride (_key, _value); } } @@ -81,11 +81,10 @@ namespace Gui } else { - EditBox::setPropertyOverride (_key, _value); + Gui::EditBox::setPropertyOverride (_key, _value); } } - MyGUI::IntSize AutoSizedButton::getRequestedSize() { MyGUI::IntSize padding(24, 8); @@ -111,16 +110,14 @@ namespace Gui } else { - Button::setPropertyOverride (_key, _value); + Gui::Button::setPropertyOverride (_key, _value); } } - Box::Box() : mSpacing(4) , mPadding(0) , mAutoResize(false) { - } void Box::notifyChildrenSizeChanged () diff --git a/components/widgets/box.hpp b/components/widgets/box.hpp index 66be00719..9bab575c4 100644 --- a/components/widgets/box.hpp +++ b/components/widgets/box.hpp @@ -4,10 +4,27 @@ #include #include #include +#include #include +#include "fontwrapper.hpp" + namespace Gui { + class Button : public FontWrapper + { + MYGUI_RTTI_DERIVED( Button ) + }; + + class TextBox : public FontWrapper + { + MYGUI_RTTI_DERIVED( TextBox ) + }; + + class EditBox : public FontWrapper + { + MYGUI_RTTI_DERIVED( EditBox ) + }; class AutoSizedWidget { @@ -22,7 +39,7 @@ namespace Gui MyGUI::Align mExpandDirection; }; - class AutoSizedTextBox : public AutoSizedWidget, public MyGUI::TextBox + class AutoSizedTextBox : public AutoSizedWidget, public TextBox { MYGUI_RTTI_DERIVED( AutoSizedTextBox ) @@ -32,9 +49,10 @@ namespace Gui protected: virtual void setPropertyOverride(const std::string& _key, const std::string& _value); + std::string mFontSize; }; - class AutoSizedEditBox : public AutoSizedWidget, public MyGUI::EditBox + class AutoSizedEditBox : public AutoSizedWidget, public EditBox { MYGUI_RTTI_DERIVED( AutoSizedEditBox ) @@ -47,9 +65,10 @@ namespace Gui protected: virtual void setPropertyOverride(const std::string& _key, const std::string& _value); + std::string mFontSize; }; - class AutoSizedButton : public AutoSizedWidget, public MyGUI::Button + class AutoSizedButton : public AutoSizedWidget, public Button { MYGUI_RTTI_DERIVED( AutoSizedButton ) @@ -59,6 +78,7 @@ namespace Gui protected: virtual void setPropertyOverride(const std::string& _key, const std::string& _value); + std::string mFontSize; }; /** diff --git a/components/widgets/fontwrapper.hpp b/components/widgets/fontwrapper.hpp new file mode 100644 index 000000000..2424b22a7 --- /dev/null +++ b/components/widgets/fontwrapper.hpp @@ -0,0 +1,45 @@ +#ifndef OPENMW_WIDGETS_WRAPPER_H +#define OPENMW_WIDGETS_WRAPPER_H + +#include "widgets.hpp" + +#include + +namespace Gui +{ + template + class FontWrapper : public T + { + public: + virtual void setFontName(const std::string& name) + { + T::setFontName(name); + T::setPropertyOverride ("FontHeight", mFontSize); + } + + protected: + FontWrapper() + { + // Note: we can not use the WindowManager here, so there is a code duplication a bit. + int fontSize = Settings::Manager::getInt("font size", "GUI"); + fontSize = std::min(std::max(12, fontSize), 20); + mFontSize = std::to_string(fontSize); + } + + virtual void setPropertyOverride(const std::string& _key, const std::string& _value) + { + T::setPropertyOverride (_key, _value); + + // There is a bug in MyGUI: when it initializes the FontName property, it reset the font height. + // We should restore it. + if (_key == "FontName") + { + T::setPropertyOverride ("FontHeight", mFontSize); + } + } + + std::string mFontSize; + }; +} + +#endif diff --git a/components/widgets/numericeditbox.hpp b/components/widgets/numericeditbox.hpp index ca7674f22..3edae2fc7 100644 --- a/components/widgets/numericeditbox.hpp +++ b/components/widgets/numericeditbox.hpp @@ -3,13 +3,15 @@ #include +#include "fontwrapper.hpp" + namespace Gui { /** * @brief A variant of the EditBox that only allows integer inputs */ - class NumericEditBox : public MyGUI::EditBox + class NumericEditBox : public FontWrapper { MYGUI_RTTI_DERIVED(NumericEditBox) @@ -17,7 +19,8 @@ namespace Gui NumericEditBox() : mValue(0), mMinValue(std::numeric_limits::min()), mMaxValue(std::numeric_limits::max()) - {} + { + } void initialiseOverride(); void shutdownOverride(); diff --git a/components/widgets/sharedstatebutton.cpp b/components/widgets/sharedstatebutton.cpp index 6859a3065..f4456275b 100644 --- a/components/widgets/sharedstatebutton.cpp +++ b/components/widgets/sharedstatebutton.cpp @@ -7,7 +7,6 @@ namespace Gui : mIsMousePressed(false) , mIsMouseFocus(false) { - } void SharedStateButton::shutdownOverride() diff --git a/components/widgets/sharedstatebutton.hpp b/components/widgets/sharedstatebutton.hpp index 3d7fbc84e..414349396 100644 --- a/components/widgets/sharedstatebutton.hpp +++ b/components/widgets/sharedstatebutton.hpp @@ -3,6 +3,8 @@ #include +#include "fontwrapper.hpp" + namespace Gui { @@ -11,7 +13,7 @@ namespace Gui typedef std::vector ButtonGroup; /// @brief A button that applies its own state changes to other widgets, to do this you define it as part of a ButtonGroup. - class SharedStateButton : public MyGUI::Button + class SharedStateButton : public FontWrapper { MYGUI_RTTI_DERIVED(SharedStateButton) diff --git a/components/widgets/widgets.cpp b/components/widgets/widgets.cpp index 92f2084df..c1a9a5053 100644 --- a/components/widgets/widgets.cpp +++ b/components/widgets/widgets.cpp @@ -18,9 +18,12 @@ namespace Gui MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); diff --git a/components/widgets/widgets.hpp b/components/widgets/widgets.hpp index d17132135..a5ba84b11 100644 --- a/components/widgets/widgets.hpp +++ b/components/widgets/widgets.hpp @@ -1,9 +1,10 @@ #ifndef OPENMW_COMPONENTS_WIDGETS_H #define OPENMW_COMPONENTS_WIDGETS_H +extern int GuiFontHeight; + namespace Gui { - /// Register all widgets from this component with MyGUI's factory manager. void registerAllWidgets(); diff --git a/docs/source/reference/modding/settings/GUI.rst b/docs/source/reference/modding/settings/GUI.rst index 3040fc48b..3fe943b6f 100644 --- a/docs/source/reference/modding/settings/GUI.rst +++ b/docs/source/reference/modding/settings/GUI.rst @@ -12,6 +12,27 @@ This setting scales the GUI interface windows. A value of 1.0 results in the normal scale. Larger values are useful to increase the scale of the GUI for high resolution displays. This setting can only be configured by editing the settings configuration file. +font size +--------- + +:Type: integer +:Range: 12 to 20 +:Default: 16 + +Allows to specify glyph size for in-game fonts. +Note: default bitmap fonts are supposed to work with 16px size, otherwise glyphs will be blurry. +TrueType fonts do not have this issue. + +ttf resolution +-------------- + +:Type: integer +:Range: > 0 +:Default: 96 + +Allows to specify resolution for in-game TrueType fonts. +Note: actual resolution depends on "scaling factor" setting value, this value is for 1.0 or lower scaling factor. + menu transparency ----------------- diff --git a/files/mygui/core.skin b/files/mygui/core.skin index 9aa566451..ee9135554 100644 --- a/files/mygui/core.skin +++ b/files/mygui/core.skin @@ -2,7 +2,6 @@ - diff --git a/files/mygui/openmw_confirmation_dialog.layout b/files/mygui/openmw_confirmation_dialog.layout index c5eb573a7..246c8aa8f 100644 --- a/files/mygui/openmw_confirmation_dialog.layout +++ b/files/mygui/openmw_confirmation_dialog.layout @@ -13,7 +13,7 @@ - + diff --git a/files/mygui/openmw_enchanting_dialog.layout b/files/mygui/openmw_enchanting_dialog.layout index ed3cfb03e..4738cdc13 100644 --- a/files/mygui/openmw_enchanting_dialog.layout +++ b/files/mygui/openmw_enchanting_dialog.layout @@ -50,7 +50,7 @@ - + diff --git a/files/mygui/openmw_font.xml b/files/mygui/openmw_font.xml index e4037561d..6ffe3017e 100644 --- a/files/mygui/openmw_font.xml +++ b/files/mygui/openmw_font.xml @@ -2,8 +2,6 @@ - - diff --git a/files/mygui/openmw_inventory_window.layout b/files/mygui/openmw_inventory_window.layout index 6221799b5..e935e2f5c 100644 --- a/files/mygui/openmw_inventory_window.layout +++ b/files/mygui/openmw_inventory_window.layout @@ -29,7 +29,7 @@ - + diff --git a/files/mygui/openmw_journal.layout b/files/mygui/openmw_journal.layout index 964b5ea95..0d3a71ab5 100644 --- a/files/mygui/openmw_journal.layout +++ b/files/mygui/openmw_journal.layout @@ -59,8 +59,9 @@ - - + + + diff --git a/files/mygui/openmw_journal.skin.xml b/files/mygui/openmw_journal.skin.xml index 42be2bb62..e9eecba79 100644 --- a/files/mygui/openmw_journal.skin.xml +++ b/files/mygui/openmw_journal.skin.xml @@ -13,11 +13,9 @@ + - - - - + diff --git a/files/mygui/openmw_list.skin.xml b/files/mygui/openmw_list.skin.xml index 5b6f14dd5..9af0e7966 100644 --- a/files/mygui/openmw_list.skin.xml +++ b/files/mygui/openmw_list.skin.xml @@ -127,7 +127,6 @@ - @@ -140,8 +139,6 @@ - - @@ -153,7 +150,6 @@ - diff --git a/files/mygui/openmw_windows.skin.xml b/files/mygui/openmw_windows.skin.xml index a272ae84a..ef618b316 100644 --- a/files/mygui/openmw_windows.skin.xml +++ b/files/mygui/openmw_windows.skin.xml @@ -156,10 +156,10 @@ - + - + @@ -443,7 +443,6 @@ - @@ -458,7 +457,6 @@ ------------------------------------------------------ --> - @@ -593,7 +591,6 @@ - @@ -730,7 +727,6 @@ - diff --git a/files/settings-default.cfg b/files/settings-default.cfg index c2ac2eb1c..45cee0559 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -142,6 +142,12 @@ global = false # Scales GUI window and widget size. (<1.0 is smaller, >1.0 is larger). scaling factor = 1.0 +# Size of in-game fonts +font size = 16 + +# Resolution of TrueType fonts glyphs +ttf resolution = 96 + # Transparency of GUI windows (0.0 to 1.0, transparent to opaque). menu transparency = 0.84 From 8da099713e8c7a7535a2932dfe454013feb16f85 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 1 Sep 2018 22:02:43 +0400 Subject: [PATCH 2/6] Minor layout fixes to fit different font size --- files/mygui/openmw_alchemy_window.layout | 2 +- files/mygui/openmw_chargen_birth.layout | 2 +- files/mygui/openmw_chargen_class.layout | 6 ++-- .../mygui/openmw_chargen_create_class.layout | 6 ++-- ...penmw_chargen_generate_class_result.layout | 2 +- files/mygui/openmw_chargen_race.layout | 16 ++++----- .../openmw_chargen_select_attribute.layout | 31 +++++++++-------- .../mygui/openmw_chargen_select_skill.layout | 33 ++++++++++--------- ...penmw_chargen_select_specialization.layout | 11 ++++--- files/mygui/openmw_container_window.layout | 2 +- files/mygui/openmw_count_window.layout | 6 ++-- files/mygui/openmw_trade_window.layout | 4 +-- 12 files changed, 65 insertions(+), 56 deletions(-) diff --git a/files/mygui/openmw_alchemy_window.layout b/files/mygui/openmw_alchemy_window.layout index a8e5431fb..edc9a4c3d 100644 --- a/files/mygui/openmw_alchemy_window.layout +++ b/files/mygui/openmw_alchemy_window.layout @@ -74,7 +74,7 @@ - + diff --git a/files/mygui/openmw_chargen_birth.layout b/files/mygui/openmw_chargen_birth.layout index a137d83d1..18d412340 100644 --- a/files/mygui/openmw_chargen_birth.layout +++ b/files/mygui/openmw_chargen_birth.layout @@ -16,7 +16,7 @@ > - + diff --git a/files/mygui/openmw_chargen_class.layout b/files/mygui/openmw_chargen_class.layout index 98c8e4fde..1402d9b5c 100644 --- a/files/mygui/openmw_chargen_class.layout +++ b/files/mygui/openmw_chargen_class.layout @@ -27,11 +27,11 @@ - + - + @@ -73,7 +73,7 @@ - + diff --git a/files/mygui/openmw_chargen_create_class.layout b/files/mygui/openmw_chargen_create_class.layout index c04cfe064..fe491eb6d 100644 --- a/files/mygui/openmw_chargen_create_class.layout +++ b/files/mygui/openmw_chargen_create_class.layout @@ -11,7 +11,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -74,7 +74,7 @@ - + diff --git a/files/mygui/openmw_chargen_generate_class_result.layout b/files/mygui/openmw_chargen_generate_class_result.layout index d49f57dde..48a203b18 100644 --- a/files/mygui/openmw_chargen_generate_class_result.layout +++ b/files/mygui/openmw_chargen_generate_class_result.layout @@ -24,7 +24,7 @@ - + diff --git a/files/mygui/openmw_chargen_race.layout b/files/mygui/openmw_chargen_race.layout index 31f0436d5..ea7ec6179 100644 --- a/files/mygui/openmw_chargen_race.layout +++ b/files/mygui/openmw_chargen_race.layout @@ -1,7 +1,7 @@ - + @@ -54,28 +54,28 @@ - + - + - + - + - + - + - + diff --git a/files/mygui/openmw_chargen_select_attribute.layout b/files/mygui/openmw_chargen_select_attribute.layout index 0821d4a57..57bd4ebc6 100644 --- a/files/mygui/openmw_chargen_select_attribute.layout +++ b/files/mygui/openmw_chargen_select_attribute.layout @@ -1,28 +1,31 @@ - - + + - + - - - - - - - - + + + + + + + + - - - + + + + + + diff --git a/files/mygui/openmw_chargen_select_skill.layout b/files/mygui/openmw_chargen_select_skill.layout index d1061882d..3737ea904 100644 --- a/files/mygui/openmw_chargen_select_skill.layout +++ b/files/mygui/openmw_chargen_select_skill.layout @@ -1,10 +1,10 @@ - - + + - + @@ -44,20 +44,23 @@ - - - - - - - - - + + + + + + + + + - - - + + + + + + diff --git a/files/mygui/openmw_chargen_select_specialization.layout b/files/mygui/openmw_chargen_select_specialization.layout index c4fe6c631..47dc32f62 100644 --- a/files/mygui/openmw_chargen_select_specialization.layout +++ b/files/mygui/openmw_chargen_select_specialization.layout @@ -2,7 +2,7 @@ - + @@ -22,9 +22,12 @@ - - - + + + + + + diff --git a/files/mygui/openmw_container_window.layout b/files/mygui/openmw_container_window.layout index 6bb585e50..5783779db 100644 --- a/files/mygui/openmw_container_window.layout +++ b/files/mygui/openmw_container_window.layout @@ -9,7 +9,7 @@ - + diff --git a/files/mygui/openmw_count_window.layout b/files/mygui/openmw_count_window.layout index 520d49fa3..2e083dcea 100644 --- a/files/mygui/openmw_count_window.layout +++ b/files/mygui/openmw_count_window.layout @@ -16,12 +16,12 @@ - + - + - + diff --git a/files/mygui/openmw_trade_window.layout b/files/mygui/openmw_trade_window.layout index 0af9d59fe..30e22302d 100644 --- a/files/mygui/openmw_trade_window.layout +++ b/files/mygui/openmw_trade_window.layout @@ -48,7 +48,7 @@ - + @@ -62,7 +62,7 @@ - + From f89393fd6244e38ff4abed1f7a317d29599dc453 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 2 Sep 2018 18:08:49 +0400 Subject: [PATCH 3/6] Validate 'ttf resolution' option value --- apps/openmw/mwgui/windowmanagerimp.cpp | 2 +- docs/source/reference/modding/settings/GUI.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 493a14a1c..03cbc3ef2 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -309,7 +309,7 @@ namespace MWGui // to allow to configure font size via config file, without need to edit XML file. // Also we should take UI scaling factor in account int resolution = Settings::Manager::getInt("ttf resolution", "GUI"); - resolution = std::max(0, resolution); + resolution = std::min(960, std::max(48, resolution)); float uiScale = Settings::Manager::getFloat("scaling factor", "GUI"); diff --git a/docs/source/reference/modding/settings/GUI.rst b/docs/source/reference/modding/settings/GUI.rst index 3fe943b6f..2092096c9 100644 --- a/docs/source/reference/modding/settings/GUI.rst +++ b/docs/source/reference/modding/settings/GUI.rst @@ -27,7 +27,7 @@ ttf resolution -------------- :Type: integer -:Range: > 0 +:Range: 48 to 960 :Default: 96 Allows to specify resolution for in-game TrueType fonts. From c9c0230d2ac6a2fb8798608cf36c3ec487a9ab27 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 3 Sep 2018 20:45:04 +0400 Subject: [PATCH 4/6] Scale journal fonts separately from common ones --- apps/openmw/mwgui/bookpage.cpp | 23 +++++-- apps/openmw/mwgui/bookpage.hpp | 2 +- apps/openmw/mwgui/formatting.cpp | 2 +- apps/openmw/mwgui/formatting.hpp | 2 +- apps/openmw/mwgui/windowmanagerimp.cpp | 67 +++++++++++++++---- components/fontloader/fontloader.cpp | 15 +++++ components/sdlutil/sdlvideowrapper.cpp | 5 ++ .../source/reference/modding/settings/GUI.rst | 2 +- files/mygui/openmw_book.layout | 2 + files/mygui/openmw_journal.layout | 2 + files/mygui/openmw_journal.skin.xml | 4 +- 11 files changed, 102 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwgui/bookpage.cpp b/apps/openmw/mwgui/bookpage.cpp index 8f2e8b5ed..8e264312e 100644 --- a/apps/openmw/mwgui/bookpage.cpp +++ b/apps/openmw/mwgui/bookpage.cpp @@ -264,18 +264,29 @@ struct TypesetBookImpl::Typesetter : BookTypesetter { } - Style * createStyle (char const * fontName, const Colour& fontColour) + Style * createStyle (const std::string& fontName, const Colour& fontColour) { - if (strcmp(fontName, "") == 0) - return createStyle(MyGUI::FontManager::getInstance().getDefaultFont().c_str(), fontColour); + const std::string templateName = "Journalbook "; + std::string bookFont; + if (fontName.empty()) + { + bookFont = MyGUI::FontManager::getInstance().getDefaultFont(); + bookFont = templateName + bookFont; + return createStyle(bookFont, fontColour); + } + + if (fontName.compare(0, templateName.size(), templateName) == 0) + bookFont = fontName; + else + bookFont = templateName + bookFont; for (Styles::iterator i = mBook->mStyles.begin (); i != mBook->mStyles.end (); ++i) - if (i->match (fontName, fontColour, fontColour, fontColour, 0)) + if (i->match (bookFont.c_str(), fontColour, fontColour, fontColour, 0)) return &*i; - MyGUI::IFont* font = MyGUI::FontManager::getInstance().getByName(fontName); + MyGUI::IFont* font = MyGUI::FontManager::getInstance().getByName(bookFont); if (!font) - throw std::runtime_error(std::string("can't find font ") + fontName); + throw std::runtime_error(std::string("can't find font ") + bookFont); StyleImpl & style = *mBook->mStyles.insert (mBook->mStyles.end (), StyleImpl ()); style.mFont = font; diff --git a/apps/openmw/mwgui/bookpage.hpp b/apps/openmw/mwgui/bookpage.hpp index b8174bd3d..c75f00ca4 100644 --- a/apps/openmw/mwgui/bookpage.hpp +++ b/apps/openmw/mwgui/bookpage.hpp @@ -102,7 +102,7 @@ namespace MWGui static Ptr create (int pageWidth, int pageHeight); /// Create a simple text style consisting of a font and a text color. - virtual Style* createStyle (char const * Font, const Colour& Colour) = 0; + virtual Style* createStyle (const std::string& fontName, const Colour& colour) = 0; /// Create a hyper-link style with a user-defined identifier based on an /// existing style. The unique flag forces a new instance of this style diff --git a/apps/openmw/mwgui/formatting.cpp b/apps/openmw/mwgui/formatting.cpp index 157aeba26..fd5ed4faa 100644 --- a/apps/openmw/mwgui/formatting.cpp +++ b/apps/openmw/mwgui/formatting.cpp @@ -377,7 +377,7 @@ namespace MWGui if (attr.find("face") != attr.end()) { std::string face = attr.at("face"); - mTextStyle.mFont = face; + mTextStyle.mFont = "Journalbook "+face; } if (attr.find("size") != attr.end()) { diff --git a/apps/openmw/mwgui/formatting.hpp b/apps/openmw/mwgui/formatting.hpp index 7ccb0824e..6d98d48b3 100644 --- a/apps/openmw/mwgui/formatting.hpp +++ b/apps/openmw/mwgui/formatting.hpp @@ -14,7 +14,7 @@ namespace MWGui { TextStyle() : mColour(0,0,0) - , mFont("Default") + , mFont("") , mTextSize(16) { } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 03cbc3ef2..f4723da47 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -293,47 +293,90 @@ namespace MWGui void WindowManager::loadFontDelegate(MyGUI::xml::ElementPtr _node, const std::string& _file, MyGUI::Version _version) { - MyGUI::xml::ElementEnumerator root = _node->getElementEnumerator(); - while (root.next("Resource")) + const std::string templateName = "Journalbook "; + MyGUI::xml::ElementEnumerator font = _node->getElementEnumerator(); + bool createCopy = false; + while (font.next("Resource")) { std::string type, name; - root->findAttribute("type", type); - root->findAttribute("name", name); + font->findAttribute("type", type); + font->findAttribute("name", name); if (name.empty()) continue; if (Misc::StringUtils::ciEqual(type, "ResourceTrueTypeFont")) { + createCopy = true; + // For TrueType fonts we should override Size and Resolution properties - // to allow to configure font size via config file, without need to edit XML file. - // Also we should take UI scaling factor in account + // to allow to configure font size via config file, without need to edit XML files. + // Also we should take UI scaling factor in account. int resolution = Settings::Manager::getInt("ttf resolution", "GUI"); resolution = std::min(960, std::max(48, resolution)); float uiScale = Settings::Manager::getFloat("scaling factor", "GUI"); + resolution *= uiScale; - if (uiScale > 1.0f) - resolution *= uiScale; - - MyGUI::xml::ElementPtr resolutionNode = root->createChild("Property"); + MyGUI::xml::ElementPtr resolutionNode = font->createChild("Property"); resolutionNode->addAttribute("key", "Resolution"); resolutionNode->addAttribute("value", std::to_string(resolution)); - MyGUI::xml::ElementPtr sizeNode = root->createChild("Property"); + MyGUI::xml::ElementPtr sizeNode = font->createChild("Property"); sizeNode->addAttribute("key", "Size"); sizeNode->addAttribute("value", std::to_string(mFontHeight)); } else if (Misc::StringUtils::ciEqual(type, "ResourceSkin")) { // We should adjust line height for MyGUI widgets depending on font size - MyGUI::xml::ElementPtr heightNode = root->createChild("Property"); + MyGUI::xml::ElementPtr heightNode = font->createChild("Property"); heightNode->addAttribute("key", "HeightLine"); heightNode->addAttribute("value", std::to_string(mFontHeight+2)); } } MyGUI::ResourceManager::getInstance().loadFromXmlNode(_node, _file, _version); + + if (createCopy) + { + MyGUI::xml::ElementPtr copy = _node->createCopy(); + + MyGUI::xml::ElementEnumerator copyFont = copy->getElementEnumerator(); + while (copyFont.next("Resource")) + { + std::string type, name; + copyFont->findAttribute("type", type); + copyFont->findAttribute("name", name); + + if (name.empty()) + continue; + + if (Misc::StringUtils::ciEqual(type, "ResourceTrueTypeFont")) + { + // Since the journal and books use the custom scaling factor depending on resolution, + // setup separate fonts with different Resolution to fit these windows. + // These fonts have an internal prefix. + int resolution = Settings::Manager::getInt("ttf resolution", "GUI"); + resolution = std::min(960, std::max(48, resolution)); + + float currentX = Settings::Manager::getInt("resolution x", "Video"); + float currentY = Settings::Manager::getInt("resolution y", "Video"); + // TODO: read size from openmw_layout.xml + float heightScale = (currentY / 520); + float widthScale = (currentX / 600); + float uiScale = std::min(widthScale, heightScale); + resolution *= uiScale; + + MyGUI::xml::ElementPtr resolutionNode = copyFont->createChild("Property"); + resolutionNode->addAttribute("key", "Resolution"); + resolutionNode->addAttribute("value", std::to_string(resolution)); + + copyFont->setAttribute("name", "Journalbook " + name); + } + } + + MyGUI::ResourceManager::getInstance().loadFromXmlNode(copy, _file, _version); + } } void WindowManager::initUI() diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index 37214a038..adcdd2d14 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -480,6 +480,14 @@ namespace Gui font->deserialization(root, MyGUI::Version(3,2,0)); + // Setup "book" version of font as fallback if we will not use TrueType fonts + MyGUI::ResourceManualFont* bookFont = static_cast( + MyGUI::FactoryManager::getInstance().createObject("Resource", "ResourceManualFont")); + mFonts.push_back(bookFont); + bookFont->deserialization(root, MyGUI::Version(3,2,0)); + bookFont->setResourceName("Journalbook " + resourceName); + + // Remove automatically registered fonts for (std::vector::iterator it = mFonts.begin(); it != mFonts.end();) { if ((*it)->getResourceName() == font->getResourceName()) @@ -487,10 +495,17 @@ namespace Gui MyGUI::ResourceManager::getInstance().removeByName(font->getResourceName()); it = mFonts.erase(it); } + else if ((*it)->getResourceName() == bookFont->getResourceName()) + { + MyGUI::ResourceManager::getInstance().removeByName(bookFont->getResourceName()); + it = mFonts.erase(it); + } else ++it; } + MyGUI::ResourceManager::getInstance().addResource(font); + MyGUI::ResourceManager::getInstance().addResource(bookFont); } } diff --git a/components/sdlutil/sdlvideowrapper.cpp b/components/sdlutil/sdlvideowrapper.cpp index c2963be86..d5c8833ea 100644 --- a/components/sdlutil/sdlvideowrapper.cpp +++ b/components/sdlutil/sdlvideowrapper.cpp @@ -2,6 +2,8 @@ #include +#include + #include #include @@ -89,6 +91,9 @@ namespace SDLUtil SDL_SetWindowSize(mWindow, width, height); SDL_SetWindowBordered(mWindow, windowBorder ? SDL_TRUE : SDL_FALSE); } + + // We should reload TrueType fonts for new resolution + MyGUI::ResourceManager::getInstance().load("openmw_font.xml"); } } diff --git a/docs/source/reference/modding/settings/GUI.rst b/docs/source/reference/modding/settings/GUI.rst index 2092096c9..c8f4e16f8 100644 --- a/docs/source/reference/modding/settings/GUI.rst +++ b/docs/source/reference/modding/settings/GUI.rst @@ -31,7 +31,7 @@ ttf resolution :Default: 96 Allows to specify resolution for in-game TrueType fonts. -Note: actual resolution depends on "scaling factor" setting value, this value is for 1.0 or lower scaling factor. +Note: actual resolution depends on "scaling factor" setting value, this value is for 1.0 scaling factor. menu transparency ----------------- diff --git a/files/mygui/openmw_book.layout b/files/mygui/openmw_book.layout index c83c4982b..e6f0f858c 100644 --- a/files/mygui/openmw_book.layout +++ b/files/mygui/openmw_book.layout @@ -32,11 +32,13 @@ + + diff --git a/files/mygui/openmw_journal.layout b/files/mygui/openmw_journal.layout index 0d3a71ab5..5d6e29066 100644 --- a/files/mygui/openmw_journal.layout +++ b/files/mygui/openmw_journal.layout @@ -25,10 +25,12 @@ + + diff --git a/files/mygui/openmw_journal.skin.xml b/files/mygui/openmw_journal.skin.xml index e9eecba79..0702d8c5e 100644 --- a/files/mygui/openmw_journal.skin.xml +++ b/files/mygui/openmw_journal.skin.xml @@ -2,7 +2,7 @@ - + @@ -19,7 +19,7 @@ - + From 7a986f38da71544f1d9f6965942ba7463c1e7055 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 4 Sep 2018 09:15:07 +0400 Subject: [PATCH 5/6] Support for user-defined TrueType fonts --- apps/openmw/engine.cpp | 2 +- apps/openmw/mwbase/windowmanager.hpp | 2 ++ apps/openmw/mwgui/windowmanagerimp.cpp | 15 +++++++++++---- apps/openmw/mwgui/windowmanagerimp.hpp | 5 +++-- apps/openmw/mwinput/inputmanagerimp.cpp | 3 +++ components/fontloader/fontloader.cpp | 24 ++++++++++++++++++++++-- components/fontloader/fontloader.hpp | 9 +++++++-- components/sdlutil/sdlvideowrapper.cpp | 5 ----- 8 files changed, 49 insertions(+), 16 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 2941ede1b..057113ba3 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -516,7 +516,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) MWGui::WindowManager* window = new MWGui::WindowManager(mViewer, guiRoot, mResourceSystem.get(), mWorkQueue.get(), mCfgMgr.getLogPath().string() + std::string("/"), myguiResources, mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts, mFallbackMap, - Version::getOpenmwVersionDescription(mResDir.string())); + Version::getOpenmwVersionDescription(mResDir.string()), mCfgMgr.getUserConfigPath().string()); mEnvironment.setWindowManager (window); // Create sound system diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index b40f517f9..fb0be30e4 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -290,6 +290,8 @@ namespace MWBase /// Warning: do not use MyGUI::InputManager::setKeyFocusWidget directly. Instead use this. virtual void setKeyFocusWidget (MyGUI::Widget* widget) = 0; + virtual void loadUserFonts() = 0; + virtual Loading::Listener* getLoadingScreen() = 0; /// Should the cursor be visible? diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index f4723da47..481a9ec00 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -131,8 +132,8 @@ namespace MWGui WindowManager::WindowManager( osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, - const std::string& logpath, const std::string& resourcePath, bool consoleOnlyScripts, - Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, bool exportFonts, const std::map& fallbackMap, const std::string& versionDescription) + const std::string& logpath, const std::string& resourcePath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, + ToUTF8::FromType encoding, bool exportFonts, const std::map& fallbackMap, const std::string& versionDescription, const std::string& userDataPath) : mStore(NULL) , mResourceSystem(resourceSystem) , mWorkQueue(workQueue) @@ -210,8 +211,8 @@ namespace MWGui MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag); // Load fonts - mFontLoader.reset(new Gui::FontLoader(encoding, resourceSystem->getVFS())); - mFontLoader->loadAllFonts(exportFonts); + mFontLoader.reset(new Gui::FontLoader(encoding, resourceSystem->getVFS(), userDataPath)); + mFontLoader->loadBitmapFonts(exportFonts); //Register own widgets with MyGUI MyGUI::FactoryManager::getInstance().registerFactory("Widget"); @@ -245,6 +246,7 @@ namespace MWGui MyGUI::FactoryManager::getInstance().registerFactory("Resource", "ResourceImageSetPointer"); MyGUI::ResourceManager::getInstance().load("core.xml"); + loadUserFonts(); bool keyboardNav = Settings::Manager::getBool("keyboard navigation", "GUI"); mKeyboardNavigation.reset(new KeyboardNavigation()); @@ -379,6 +381,11 @@ namespace MWGui } } + void WindowManager::loadUserFonts() + { + mFontLoader->loadTrueTypeFonts(); + } + void WindowManager::initUI() { // Get size info from the Gui object diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index f3bf6d00f..547701496 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -131,14 +131,15 @@ namespace MWGui typedef std::vector FactionList; WindowManager(osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, - const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, - Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, bool exportFonts, const std::map& fallbackMap, const std::string& versionDescription); + const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, + ToUTF8::FromType encoding, bool exportFonts, const std::map& fallbackMap, const std::string& versionDescription, const std::string& localPath); virtual ~WindowManager(); /// Set the ESMStore to use for retrieving of GUI-related strings. void setStore (const MWWorld::ESMStore& store); void initUI(); + virtual void loadUserFonts(); virtual Loading::Listener* getLoadingScreen(); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index b24c8cc14..ec9ead595 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -676,6 +676,9 @@ namespace MWInput Settings::Manager::getInt("resolution y", "Video"), Settings::Manager::getBool("fullscreen", "Video"), Settings::Manager::getBool("window border", "Video")); + + // We should reload TrueType fonts to fit new resolution + MWBase::Environment::get().getWindowManager()->loadUserFonts(); } } diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index adcdd2d14..0378e294e 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -145,8 +145,9 @@ namespace namespace Gui { - FontLoader::FontLoader(ToUTF8::FromType encoding, const VFS::Manager* vfs) + FontLoader::FontLoader(ToUTF8::FromType encoding, const VFS::Manager* vfs, const std::string& userDataPath) : mVFS(vfs) + , mUserDataPath(userDataPath) { if (encoding == ToUTF8::WINDOWS_1252) mEncoding = ToUTF8::CP437; @@ -175,7 +176,7 @@ namespace Gui mFonts.clear(); } - void FontLoader::loadAllFonts(bool exportToFile) + void FontLoader::loadBitmapFonts(bool exportToFile) { const std::map& index = mVFS->getIndex(); @@ -198,6 +199,25 @@ namespace Gui } } + void FontLoader::loadTrueTypeFonts() + { + osgMyGUI::DataManager* dataManager = dynamic_cast(&osgMyGUI::DataManager::getInstance()); + if (!dataManager) + { + Log(Debug::Error) << "Can not load TrueType fonts: osgMyGUI::DataManager is not available."; + return; + } + + const std::string cfg = dataManager->getDataPath(""); + const std::string fontFile = mUserDataPath + "/" + "Fonts" + "/" + "openmw_font.xml"; + if (!boost::filesystem::exists(fontFile)) + return; + + dataManager->setResourcePath(mUserDataPath + "/" + "Fonts"); + MyGUI::ResourceManager::getInstance().load("openmw_font.xml"); + dataManager->setResourcePath(cfg); + } + typedef struct { diff --git a/components/fontloader/fontloader.hpp b/components/fontloader/fontloader.hpp index b92815f13..39301f9f5 100644 --- a/components/fontloader/fontloader.hpp +++ b/components/fontloader/fontloader.hpp @@ -1,6 +1,9 @@ #ifndef OPENMW_COMPONENTS_FONTLOADER_H #define OPENMW_COMPONENTS_FONTLOADER_H +#include "boost/filesystem/operations.hpp" + +#include #include namespace VFS @@ -23,15 +26,17 @@ namespace Gui class FontLoader { public: - FontLoader (ToUTF8::FromType encoding, const VFS::Manager* vfs); + FontLoader (ToUTF8::FromType encoding, const VFS::Manager* vfs, const std::string& userDataPath); ~FontLoader(); /// @param exportToFile export the converted fonts (Images and XML with glyph metrics) to files? - void loadAllFonts (bool exportToFile); + void loadBitmapFonts (bool exportToFile); + void loadTrueTypeFonts (); private: ToUTF8::FromType mEncoding; const VFS::Manager* mVFS; + std::string mUserDataPath; std::vector mTextures; std::vector mFonts; diff --git a/components/sdlutil/sdlvideowrapper.cpp b/components/sdlutil/sdlvideowrapper.cpp index d5c8833ea..c2963be86 100644 --- a/components/sdlutil/sdlvideowrapper.cpp +++ b/components/sdlutil/sdlvideowrapper.cpp @@ -2,8 +2,6 @@ #include -#include - #include #include @@ -91,9 +89,6 @@ namespace SDLUtil SDL_SetWindowSize(mWindow, width, height); SDL_SetWindowBordered(mWindow, windowBorder ? SDL_TRUE : SDL_FALSE); } - - // We should reload TrueType fonts for new resolution - MyGUI::ResourceManager::getInstance().load("openmw_font.xml"); } } From e300a16b24a0f8881549f4c97afb86466ef4612b Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 4 Sep 2018 12:19:50 +0400 Subject: [PATCH 6/6] Use field for columns count instead of out integer --- apps/openmw/mwgui/journalbooks.cpp | 16 ++++++++-------- apps/openmw/mwgui/journalbooks.hpp | 7 ++++--- apps/openmw/mwgui/journalwindow.cpp | 5 ++--- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwgui/journalbooks.cpp b/apps/openmw/mwgui/journalbooks.cpp index 1956ee1c2..4302740f6 100644 --- a/apps/openmw/mwgui/journalbooks.cpp +++ b/apps/openmw/mwgui/journalbooks.cpp @@ -157,7 +157,7 @@ MWGui::BookTypesetter::Utf8Span to_utf8_span (char const * text) typedef TypesetBook::Ptr book; JournalBooks::JournalBooks (JournalViewModel::Ptr model, ToUTF8::FromType encoding) : - mModel (model), mEncoding(encoding) + mModel (model), mEncoding(encoding), mIndexPagesCount(0) { } @@ -218,23 +218,23 @@ book JournalBooks::createQuestBook (const std::string& questName) return typesetter->complete (); } -book JournalBooks::createTopicIndexBook (int& columnsCount) +book JournalBooks::createTopicIndexBook () { bool isRussian = (mEncoding == ToUTF8::WINDOWS_1251); - BookTypesetter::Ptr typesetter = isRussian ? createCyrillicJournalIndex(columnsCount) : createLatinJournalIndex(columnsCount); + BookTypesetter::Ptr typesetter = isRussian ? createCyrillicJournalIndex() : createLatinJournalIndex(); return typesetter->complete (); } -BookTypesetter::Ptr JournalBooks::createLatinJournalIndex (int& columnsCount) +BookTypesetter::Ptr JournalBooks::createLatinJournalIndex () { BookTypesetter::Ptr typesetter = BookTypesetter::create (92, 260); typesetter->setSectionAlignment (BookTypesetter::AlignCenter); // Latin journal index always has two columns for now. - columnsCount = 2; + mIndexPagesCount = 2; char ch = 'A'; @@ -261,7 +261,7 @@ BookTypesetter::Ptr JournalBooks::createLatinJournalIndex (int& columnsCount) return typesetter; } -BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex (int& columnsCount) +BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex () { BookTypesetter::Ptr typesetter = BookTypesetter::create (92, 260); @@ -273,11 +273,11 @@ BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex (int& columnsCount) // for small font size split alphabet to two columns (2x15 characers), for big font size split it to three colums (3x10 characters). int sectionBreak = 10; - columnsCount = 3; + mIndexPagesCount = 3; if (fontHeight < 18) { sectionBreak = 15; - columnsCount = 2; + mIndexPagesCount = 2; } unsigned char ch[2] = {0xd0, 0x90}; // CYRILLIC CAPITAL A is a 0xd090 in UTF-8 diff --git a/apps/openmw/mwgui/journalbooks.hpp b/apps/openmw/mwgui/journalbooks.hpp index cc6f42cc8..05eda6e22 100644 --- a/apps/openmw/mwgui/journalbooks.hpp +++ b/apps/openmw/mwgui/journalbooks.hpp @@ -22,14 +22,15 @@ namespace MWGui Book createTopicBook (uintptr_t topicId); Book createTopicBook (const std::string& topicId); Book createQuestBook (const std::string& questName); - Book createTopicIndexBook (int& columnsCount); + Book createTopicIndexBook (); ToUTF8::FromType mEncoding; + int mIndexPagesCount; private: BookTypesetter::Ptr createTypesetter (); - BookTypesetter::Ptr createLatinJournalIndex (int& columnsCount); - BookTypesetter::Ptr createCyrillicJournalIndex (int& columnsCount); + BookTypesetter::Ptr createLatinJournalIndex (); + BookTypesetter::Ptr createCyrillicJournalIndex (); }; } diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index cef20159d..a2f6ea142 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -465,11 +465,10 @@ namespace { setOptionsMode (); - int pagesCount; if (!mTopicIndexBook) - mTopicIndexBook = createTopicIndexBook (pagesCount); + mTopicIndexBook = createTopicIndexBook (); - if (pagesCount == 3) + if (mIndexPagesCount == 3) { getPage (LeftTopicIndex)->showPage (mTopicIndexBook, 0); getPage (CenterTopicIndex)->showPage (mTopicIndexBook, 1);