From 4dcaf040e670809af60a8c915b0ff113e8dd4641 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 4 Aug 2017 20:21:13 +0400 Subject: [PATCH 01/11] A Russian journal index --- apps/openmw/mwgui/journalbooks.cpp | 14 ++++++++------ apps/openmw/mwgui/journalviewmodel.cpp | 24 +++++++++++++++++++++--- apps/openmw/mwgui/journalviewmodel.hpp | 4 ++-- apps/openmw/mwgui/journalwindow.cpp | 4 ++-- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwgui/journalbooks.cpp b/apps/openmw/mwgui/journalbooks.cpp index 5634eb080..19a2a9afe 100644 --- a/apps/openmw/mwgui/journalbooks.cpp +++ b/apps/openmw/mwgui/journalbooks.cpp @@ -224,20 +224,22 @@ book JournalBooks::createTopicIndexBook () BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); - for (int i = 0; i < 26; ++i) + for (int i = 0; i < 32; ++i) { - char ch = 'A' + i; - char buffer [32]; - sprintf (buffer, "( %c )", ch); + sprintf(buffer, "( %c%c )", 0xd0, 0x90 + i); // CYRILLIC CAPITAL A is a 0xd090 in UTF-8 const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); BookTypesetter::Style* style = typesetter->createHotStyle (body, textColours.journalTopic, textColours.journalTopicOver, - textColours.journalTopicPressed, ch); + textColours.journalTopicPressed, i+1); + + // Words can not be started with these characters + if (i == 26 || i == 28) + continue; - if (i == 13) + if (i == 15) typesetter->sectionBreak (); typesetter->write (style, to_utf8_span (buffer)); diff --git a/apps/openmw/mwgui/journalviewmodel.cpp b/apps/openmw/mwgui/journalviewmodel.cpp index b5d08eec6..02103280b 100644 --- a/apps/openmw/mwgui/journalviewmodel.cpp +++ b/apps/openmw/mwgui/journalviewmodel.cpp @@ -305,18 +305,36 @@ struct JournalViewModelImpl : JournalViewModel visitor (toUtf8Span (topic.getName())); } - void visitTopicNamesStartingWith (char character, std::function < void (const std::string&) > visitor) const + void visitTopicNamesStartingWith (int index, std::function < void (const std::string&) > visitor) const { MWBase::Journal * journal = MWBase::Environment::get().getJournal(); for (MWBase::Journal::TTopicIter i = journal->topicBegin (); i != journal->topicEnd (); ++i) { - if (i->first [0] != Misc::StringUtils::toLower(character)) + if (i->first.length() < 2) + continue; + + unsigned char byte1 = i->first[0]; + unsigned char byte2 = i->first[1]; + + // Upper case + if (byte1 == 0xd0 && byte2 >= 0xb0 && byte2 < 0xc0) + byte2 -= 32; + + if (byte1 == 0xd1 && byte2 >= 0x80 && byte2 < 0x90) + { + byte1 -= 1; + byte2 += 32; + } + + // CYRILLIC CAPITAL A is a 0xd090 in UTF-8 + // so we can use 0xd08f + index + // (index is a position of letter in alphabet, begins from 1) + if (byte1 != 0xd0 || byte2 != 0x8f + index) continue; visitor (i->second.getName()); } - } struct TopicEntryImpl : BaseEntry diff --git a/apps/openmw/mwgui/journalviewmodel.hpp b/apps/openmw/mwgui/journalviewmodel.hpp index 3edde3d31..88f8acd55 100644 --- a/apps/openmw/mwgui/journalviewmodel.hpp +++ b/apps/openmw/mwgui/journalviewmodel.hpp @@ -75,8 +75,8 @@ namespace MWGui /// provides the name of the topic specified by its id virtual void visitTopicName (TopicId topicId, std::function visitor) const = 0; - /// walks over the topics whose names start with the specified character providing the topics name - virtual void visitTopicNamesStartingWith (char character, std::function < void (const std::string&) > visitor) const = 0; + /// walks over the topics whose names start with the character, specified by its index in the alphabet, providing the topics name + virtual void visitTopicNamesStartingWith (int index, std::function < void (const std::string&) > visitor) const = 0; /// walks over the topic entries for the topic specified by its identifier virtual void visitTopicEntries (TopicId topicId, std::function visitor) const = 0; diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index 105f95085..b4279e03d 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -431,7 +431,7 @@ namespace MWBase::Environment::get().getWindowManager()->playSound("book page"); } - void notifyIndexLinkClicked (MWGui::TypesetBook::InteractiveId character) + void notifyIndexLinkClicked (MWGui::TypesetBook::InteractiveId index) { setVisible (LeftTopicIndex, false); setVisible (RightTopicIndex, false); @@ -444,7 +444,7 @@ namespace AddNamesToList add(list); - mModel->visitTopicNamesStartingWith((char) character, add); + mModel->visitTopicNamesStartingWith(index, add); list->adjustSize(); From a391990f2a52695b3c56afedaea5ffb80581f1e4 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 20 Nov 2017 21:30:46 +0400 Subject: [PATCH 02/11] Provide multibyte toLower() and single chars comparator --- apps/openmw/mwgui/journalviewmodel.cpp | 46 ++++++++++++++++---------- components/misc/stringops.hpp | 30 +++++++++++++++++ 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwgui/journalviewmodel.cpp b/apps/openmw/mwgui/journalviewmodel.cpp index 02103280b..33935f040 100644 --- a/apps/openmw/mwgui/journalviewmodel.cpp +++ b/apps/openmw/mwgui/journalviewmodel.cpp @@ -311,29 +311,39 @@ struct JournalViewModelImpl : JournalViewModel for (MWBase::Journal::TTopicIter i = journal->topicBegin (); i != journal->topicEnd (); ++i) { - if (i->first.length() < 2) - continue; - unsigned char byte1 = i->first[0]; - unsigned char byte2 = i->first[1]; + // First, check for two-byte UTF-8 symbols, e.g. Cyrillic ones + // TODO: check which language journal index is using + if ((byte1 == 0xd0 || byte1 == 0xd1) && i->first.length() >= 2) + { + unsigned char byte2 = i->first[1]; - // Upper case - if (byte1 == 0xd0 && byte2 >= 0xb0 && byte2 < 0xc0) - byte2 -= 32; + std::pair symbol = Misc::StringUtils::toLower(byte1, byte2); - if (byte1 == 0xd1 && byte2 >= 0x80 && byte2 < 0x90) - { - byte1 -= 1; - byte2 += 32; - } + // CYRILLIC LETTER A - CYRILLIC LETTER PE + // index from 1 to 16 + if (symbol.first == 0xd0 && symbol.second >= (0xaf + index) && symbol.second < (0xbf + index) && symbol.second == (0xaf + index)) + { + visitor (i->second.getName()); + continue; + } - // CYRILLIC CAPITAL A is a 0xd090 in UTF-8 - // so we can use 0xd08f + index - // (index is a position of letter in alphabet, begins from 1) - if (byte1 != 0xd0 || byte2 != 0x8f + index) - continue; + // CYRILLIC LETTERL R - CYRILLIC LETTER YA + // index from 17 to 32 + if (symbol.first == 0xd1 && symbol.second >= (0x6f + index) && symbol.second < (0x7f + index) && symbol.second == (0x6f + index)) + { + visitor (i->second.getName()); + continue; + } + } + else + { + // Otherwise check for regular Latin symbols, 0x61 = 'a' + if (i->first [0] != 0x60 + index) + continue; - visitor (i->second.getName()); + visitor (i->second.getName()); + } } } diff --git a/components/misc/stringops.hpp b/components/misc/stringops.hpp index 9acd81710..97865a44c 100644 --- a/components/misc/stringops.hpp +++ b/components/misc/stringops.hpp @@ -55,6 +55,36 @@ public: }; } + static std::pair toLower(unsigned char byte1, unsigned char byte2) + { + std::pair symbol = std::make_pair(byte1, byte2); + // CYRILLIC CAPITAL IO + if (symbol.first == 0xd0 && symbol.second == 0x01) + { + symbol.first++; + symbol.second = 0x91; + } + // CYRILLIC CAPITAL A - CYRILLIC CAPITAL PE + else if (symbol.first == 0xd0 && symbol.second >= 0x90 && symbol.second < 0xa0) + { + symbol.second += 0x20; + } + // CYRILLIC CAPITAL R - CYRILLIC CAPITAL YA + else if (symbol.first == 0xd0 && symbol.second >= 0xa0 && symbol.second < 0xb0) + { + symbol.first++; + symbol.second -= 0x20; + } + // Other symbols + else + { + symbol.first = toLower(symbol.first); + symbol.second = toLower(symbol.second); + } + + return symbol; + } + static bool ciLess(const std::string &x, const std::string &y) { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end(), ci()); } From ce5bdd636183691ea7187698cb370cbf154bf522 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 20 Nov 2017 22:25:53 +0400 Subject: [PATCH 03/11] Split the JournalBooks::createTopicIndexBook() --- apps/openmw/mwgui/journalbooks.cpp | 44 ++++++++++++++++++++++++++++-- apps/openmw/mwgui/journalbooks.hpp | 2 ++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/journalbooks.cpp b/apps/openmw/mwgui/journalbooks.cpp index 19a2a9afe..b4f9147b5 100644 --- a/apps/openmw/mwgui/journalbooks.cpp +++ b/apps/openmw/mwgui/journalbooks.cpp @@ -217,19 +217,59 @@ book JournalBooks::createQuestBook (const std::string& questName) } book JournalBooks::createTopicIndexBook () +{ + // TODO: determine actual index alphabet + bool isRussian = true; + + BookTypesetter::Ptr typesetter = isRussian ? createCyrillicJournalIndex() : createLatinJournalIndex(); + + return typesetter->complete (); +} + +BookTypesetter::Ptr JournalBooks::createLatinJournalIndex () { BookTypesetter::Ptr typesetter = BookTypesetter::create (92, 250); typesetter->setSectionAlignment (BookTypesetter::AlignCenter); - BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); + BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); + for (int i = 0; i < 26; ++i) + { + char ch = 'A' + i; + char buffer [32]; + + sprintf (buffer, "( %c )", ch); + + // TODO: find a way to store a multibyte character in the InteractiveId (this is a intptr_t) + const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); + BookTypesetter::Style* style = typesetter->createHotStyle (body, textColours.journalTopic, + textColours.journalTopicOver, + textColours.journalTopicPressed, i+1); + if (i == 13) + typesetter->sectionBreak (); + + typesetter->write (style, to_utf8_span (buffer)); + typesetter->lineBreak (); + } + + return typesetter; +} + +BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex () +{ + BookTypesetter::Ptr typesetter = BookTypesetter::create (92, 250); + + typesetter->setSectionAlignment (BookTypesetter::AlignCenter); + + BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); for (int i = 0; i < 32; ++i) { char buffer [32]; sprintf(buffer, "( %c%c )", 0xd0, 0x90 + i); // CYRILLIC CAPITAL A is a 0xd090 in UTF-8 + // TODO: find a way to store a multibyte character in the InteractiveId (this is a intptr_t) const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); BookTypesetter::Style* style = typesetter->createHotStyle (body, textColours.journalTopic, textColours.journalTopicOver, @@ -246,7 +286,7 @@ book JournalBooks::createTopicIndexBook () typesetter->lineBreak (); } - return typesetter->complete (); + return typesetter; } BookTypesetter::Ptr JournalBooks::createTypesetter () diff --git a/apps/openmw/mwgui/journalbooks.hpp b/apps/openmw/mwgui/journalbooks.hpp index 8f87825f0..769f05823 100644 --- a/apps/openmw/mwgui/journalbooks.hpp +++ b/apps/openmw/mwgui/journalbooks.hpp @@ -24,6 +24,8 @@ namespace MWGui private: BookTypesetter::Ptr createTypesetter (); + BookTypesetter::Ptr createLatinJournalIndex (); + BookTypesetter::Ptr createCyrillicJournalIndex (); }; } From a83a43e37613667b956752be5f1fff049ca959ce Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 21 Nov 2017 09:32:35 +0400 Subject: [PATCH 04/11] Determine when need to use the Cyrillic journal index --- apps/openmw/mwbase/windowmanager.hpp | 3 +++ apps/openmw/mwgui/journalbooks.cpp | 6 ++++-- apps/openmw/mwgui/windowmanagerimp.cpp | 5 +++++ apps/openmw/mwgui/windowmanagerimp.hpp | 3 +++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 416a7ad87..ffcbe0502 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -9,6 +9,8 @@ #include "../mwgui/mode.hpp" +#include + namespace Loading { class Listener; @@ -365,6 +367,7 @@ namespace MWBase virtual void writeFog(MWWorld::CellStore* cell) = 0; virtual const MWGui::TextColours& getTextColours() = 0; + virtual ToUTF8::FromType getEncoding() = 0; }; } diff --git a/apps/openmw/mwgui/journalbooks.cpp b/apps/openmw/mwgui/journalbooks.cpp index b4f9147b5..73796c381 100644 --- a/apps/openmw/mwgui/journalbooks.cpp +++ b/apps/openmw/mwgui/journalbooks.cpp @@ -5,6 +5,8 @@ #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" +#include + #include "textcolours.hpp" @@ -218,8 +220,8 @@ book JournalBooks::createQuestBook (const std::string& questName) book JournalBooks::createTopicIndexBook () { - // TODO: determine actual index alphabet - bool isRussian = true; + ToUTF8::FromType encoding = MWBase::Environment::get().getWindowManager()->getEncoding(); + bool isRussian = (encoding == ToUTF8::WINDOWS_1251); BookTypesetter::Ptr typesetter = isRussian ? createCyrillicJournalIndex() : createLatinJournalIndex(); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 97aedab81..920b8c1ac 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -205,6 +205,7 @@ namespace MWGui , mRestAllowed(true) , mFallbackMap(fallbackMap) , mShowOwned(0) + , mEncoding(encoding) , mVersionDescription(versionDescription) { float uiScale = Settings::Manager::getFloat("scaling factor", "GUI"); @@ -2174,4 +2175,8 @@ namespace MWGui return mTextColours; } + ToUTF8::FromType WindowManager::getEncoding() + { + return mEncoding; + } } diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index f74ba21a3..a1ec7cdb4 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -393,6 +393,7 @@ namespace MWGui void writeFog(MWWorld::CellStore* cell); virtual const MWGui::TextColours& getTextColours(); + virtual ToUTF8::FromType getEncoding(); private: const MWWorld::ESMStore* mStore; @@ -515,6 +516,8 @@ namespace MWGui int mShowOwned; + ToUTF8::FromType mEncoding; + std::string mVersionDescription; MWGui::TextColours mTextColours; From ba91cd658b019dbf1ee93c4185333687c3e086a7 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 21 Nov 2017 12:31:23 +0400 Subject: [PATCH 05/11] Convert topic name to Unicode --- apps/openmw/mwgui/journalbooks.cpp | 19 +++++++++--- apps/openmw/mwgui/journalviewmodel.cpp | 41 ++++++-------------------- apps/openmw/mwgui/journalviewmodel.hpp | 4 +-- components/misc/stringops.hpp | 39 ++++++++---------------- 4 files changed, 39 insertions(+), 64 deletions(-) diff --git a/apps/openmw/mwgui/journalbooks.cpp b/apps/openmw/mwgui/journalbooks.cpp index 49c1aa972..3b1463b45 100644 --- a/apps/openmw/mwgui/journalbooks.cpp +++ b/apps/openmw/mwgui/journalbooks.cpp @@ -6,10 +6,10 @@ #include "../mwbase/windowmanager.hpp" #include +#include #include "textcolours.hpp" - namespace { struct AddContent @@ -242,11 +242,17 @@ BookTypesetter::Ptr JournalBooks::createLatinJournalIndex () sprintf (buffer, "( %c )", ch); + char buffer2 [32]; + sprintf(buffer2, "%c", ch); + const char * c = buffer2; + Utf8Stream stream ((unsigned char*) c,(unsigned char*) c + strlen(c)); + uint32_t first = stream.peek(); + // TODO: find a way to store a multibyte character in the InteractiveId (this is a intptr_t) const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); BookTypesetter::Style* style = typesetter->createHotStyle (body, textColours.journalTopic, textColours.journalTopicOver, - textColours.journalTopicPressed, i+1); + textColours.journalTopicPressed, first); if (i == 13) typesetter->sectionBreak (); @@ -271,11 +277,16 @@ BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex () sprintf(buffer, "( %c%c )", 0xd0, 0x90 + i); // CYRILLIC CAPITAL A is a 0xd090 in UTF-8 - // TODO: find a way to store a multibyte character in the InteractiveId (this is a intptr_t) + char buffer2 [32]; + sprintf(buffer2, "%c%c", 0xd0, 0x90 + i); + const char * c = buffer2; + Utf8Stream stream ((unsigned char*) c,(unsigned char*) c + strlen(c)); + uint32_t first = stream.peek(); + const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); BookTypesetter::Style* style = typesetter->createHotStyle (body, textColours.journalTopic, textColours.journalTopicOver, - textColours.journalTopicPressed, i+1); + textColours.journalTopicPressed, first); // Words can not be started with these characters if (i == 26 || i == 28) diff --git a/apps/openmw/mwgui/journalviewmodel.cpp b/apps/openmw/mwgui/journalviewmodel.cpp index 33935f040..3f8992e31 100644 --- a/apps/openmw/mwgui/journalviewmodel.cpp +++ b/apps/openmw/mwgui/journalviewmodel.cpp @@ -6,6 +6,8 @@ #include #include +#include +#include #include "../mwbase/world.hpp" #include "../mwbase/journal.hpp" @@ -305,45 +307,20 @@ struct JournalViewModelImpl : JournalViewModel visitor (toUtf8Span (topic.getName())); } - void visitTopicNamesStartingWith (int index, std::function < void (const std::string&) > visitor) const + void visitTopicNamesStartingWith (uint32_t character, std::function < void (const std::string&) > visitor) const { MWBase::Journal * journal = MWBase::Environment::get().getJournal(); for (MWBase::Journal::TTopicIter i = journal->topicBegin (); i != journal->topicEnd (); ++i) { - unsigned char byte1 = i->first[0]; - // First, check for two-byte UTF-8 symbols, e.g. Cyrillic ones - // TODO: check which language journal index is using - if ((byte1 == 0xd0 || byte1 == 0xd1) && i->first.length() >= 2) - { - unsigned char byte2 = i->first[1]; - - std::pair symbol = Misc::StringUtils::toLower(byte1, byte2); - - // CYRILLIC LETTER A - CYRILLIC LETTER PE - // index from 1 to 16 - if (symbol.first == 0xd0 && symbol.second >= (0xaf + index) && symbol.second < (0xbf + index) && symbol.second == (0xaf + index)) - { - visitor (i->second.getName()); - continue; - } + const char * c = i->first.c_str(); + Utf8Stream stream ((unsigned char*) c,(unsigned char*) c + strlen(c)); + uint32_t first = Misc::StringUtils::toUpper(stream.peek()); - // CYRILLIC LETTERL R - CYRILLIC LETTER YA - // index from 17 to 32 - if (symbol.first == 0xd1 && symbol.second >= (0x6f + index) && symbol.second < (0x7f + index) && symbol.second == (0x6f + index)) - { - visitor (i->second.getName()); - continue; - } - } - else - { - // Otherwise check for regular Latin symbols, 0x61 = 'a' - if (i->first [0] != 0x60 + index) - continue; + if (first != character) + continue; - visitor (i->second.getName()); - } + visitor (i->second.getName()); } } diff --git a/apps/openmw/mwgui/journalviewmodel.hpp b/apps/openmw/mwgui/journalviewmodel.hpp index 88f8acd55..01dcb49de 100644 --- a/apps/openmw/mwgui/journalviewmodel.hpp +++ b/apps/openmw/mwgui/journalviewmodel.hpp @@ -75,8 +75,8 @@ namespace MWGui /// provides the name of the topic specified by its id virtual void visitTopicName (TopicId topicId, std::function visitor) const = 0; - /// walks over the topics whose names start with the character, specified by its index in the alphabet, providing the topics name - virtual void visitTopicNamesStartingWith (int index, std::function < void (const std::string&) > visitor) const = 0; + /// walks over the topics whose names start with the character + virtual void visitTopicNamesStartingWith (uint32_t character, std::function < void (const std::string&) > visitor) const = 0; /// walks over the topic entries for the topic specified by its identifier virtual void visitTopicEntries (TopicId topicId, std::function visitor) const = 0; diff --git a/components/misc/stringops.hpp b/components/misc/stringops.hpp index 0d9c2489f..5ce5360d1 100644 --- a/components/misc/stringops.hpp +++ b/components/misc/stringops.hpp @@ -56,34 +56,21 @@ public: }; } - static std::pair toLower(unsigned char byte1, unsigned char byte2) + static uint32_t toUpper(uint32_t ch) { - std::pair symbol = std::make_pair(byte1, byte2); - // CYRILLIC CAPITAL IO - if (symbol.first == 0xd0 && symbol.second == 0x01) - { - symbol.first++; - symbol.second = 0x91; - } - // CYRILLIC CAPITAL A - CYRILLIC CAPITAL PE - else if (symbol.first == 0xd0 && symbol.second >= 0x90 && symbol.second < 0xa0) - { - symbol.second += 0x20; - } - // CYRILLIC CAPITAL R - CYRILLIC CAPITAL YA - else if (symbol.first == 0xd0 && symbol.second >= 0xa0 && symbol.second < 0xb0) - { - symbol.first++; - symbol.second -= 0x20; - } - // Other symbols - else - { - symbol.first = toLower(symbol.first); - symbol.second = toLower(symbol.second); - } + // Russian alphabete + if (ch >= 0x0430 && ch < 0x0450) + ch -= 0x20; + + // Cyrillic YO character + if (ch == 0x0451) + ch -= 0x50; + + // Latin alphabete + if (ch >= 0x61 && ch < 0x80) + ch -= 0x20; - return symbol; + return ch; } static bool ciLess(const std::string &x, const std::string &y) { From 5f41f7c48df215f160a9418dd39595c954370cf8 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 21 Nov 2017 12:59:47 +0400 Subject: [PATCH 06/11] Clean code up a bit --- apps/openmw/mwgui/journalbooks.cpp | 10 +++------- apps/openmw/mwgui/journalviewmodel.cpp | 3 +-- components/misc/stringops.hpp | 4 ++-- components/misc/utf8stream.hpp | 5 +++++ 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwgui/journalbooks.cpp b/apps/openmw/mwgui/journalbooks.cpp index 3b1463b45..68b1d8403 100644 --- a/apps/openmw/mwgui/journalbooks.cpp +++ b/apps/openmw/mwgui/journalbooks.cpp @@ -239,16 +239,13 @@ BookTypesetter::Ptr JournalBooks::createLatinJournalIndex () { char ch = 'A' + i; char buffer [32]; - sprintf (buffer, "( %c )", ch); char buffer2 [32]; sprintf(buffer2, "%c", ch); - const char * c = buffer2; - Utf8Stream stream ((unsigned char*) c,(unsigned char*) c + strlen(c)); + Utf8Stream stream (buffer2); uint32_t first = stream.peek(); - // TODO: find a way to store a multibyte character in the InteractiveId (this is a intptr_t) const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); BookTypesetter::Style* style = typesetter->createHotStyle (body, textColours.journalTopic, textColours.journalTopicOver, @@ -274,13 +271,12 @@ BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex () for (int i = 0; i < 32; ++i) { char buffer [32]; - sprintf(buffer, "( %c%c )", 0xd0, 0x90 + i); // CYRILLIC CAPITAL A is a 0xd090 in UTF-8 char buffer2 [32]; sprintf(buffer2, "%c%c", 0xd0, 0x90 + i); - const char * c = buffer2; - Utf8Stream stream ((unsigned char*) c,(unsigned char*) c + strlen(c)); + + Utf8Stream stream (buffer2); uint32_t first = stream.peek(); const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); diff --git a/apps/openmw/mwgui/journalviewmodel.cpp b/apps/openmw/mwgui/journalviewmodel.cpp index 3f8992e31..d7b233ff3 100644 --- a/apps/openmw/mwgui/journalviewmodel.cpp +++ b/apps/openmw/mwgui/journalviewmodel.cpp @@ -313,8 +313,7 @@ struct JournalViewModelImpl : JournalViewModel for (MWBase::Journal::TTopicIter i = journal->topicBegin (); i != journal->topicEnd (); ++i) { - const char * c = i->first.c_str(); - Utf8Stream stream ((unsigned char*) c,(unsigned char*) c + strlen(c)); + Utf8Stream stream (i->first.c_str()); uint32_t first = Misc::StringUtils::toUpper(stream.peek()); if (first != character) diff --git a/components/misc/stringops.hpp b/components/misc/stringops.hpp index 5ce5360d1..cec2a34a4 100644 --- a/components/misc/stringops.hpp +++ b/components/misc/stringops.hpp @@ -58,7 +58,7 @@ public: static uint32_t toUpper(uint32_t ch) { - // Russian alphabete + // Russian alphabet if (ch >= 0x0430 && ch < 0x0450) ch -= 0x20; @@ -66,7 +66,7 @@ public: if (ch == 0x0451) ch -= 0x50; - // Latin alphabete + // Latin alphabet if (ch >= 0x61 && ch < 0x80) ch -= 0x20; diff --git a/components/misc/utf8stream.hpp b/components/misc/utf8stream.hpp index 760015902..368374a64 100644 --- a/components/misc/utf8stream.hpp +++ b/components/misc/utf8stream.hpp @@ -18,6 +18,11 @@ public: { } + Utf8Stream (const char * str) : + cur ((unsigned char*) str), nxt ((unsigned char*) str), end ((unsigned char*) str + strlen(str)), val(Utf8Stream::sBadChar()) + { + } + Utf8Stream (std::pair range) : cur (range.first), nxt (range.first), end (range.second), val(Utf8Stream::sBadChar()) { From 67acb83b62861e865c0fd04ff19f8922ed74c8e7 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 21 Nov 2017 13:27:33 +0400 Subject: [PATCH 07/11] Add missing include --- components/misc/stringops.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/components/misc/stringops.hpp b/components/misc/stringops.hpp index cec2a34a4..1edb5ea61 100644 --- a/components/misc/stringops.hpp +++ b/components/misc/stringops.hpp @@ -1,6 +1,7 @@ #ifndef MISC_STRINGOPS_H #define MISC_STRINGOPS_H +#include #include #include #include From 3571f7f41379833848467c50c0ef1879c105a68c Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 22 Nov 2017 08:32:38 +0400 Subject: [PATCH 08/11] Remove getEncoding() from WindowManager --- apps/openmw/mwbase/windowmanager.hpp | 1 - apps/openmw/mwgui/journalbooks.cpp | 7 +++---- apps/openmw/mwgui/journalbooks.hpp | 6 +++++- apps/openmw/mwgui/journalwindow.cpp | 8 ++++---- apps/openmw/mwgui/journalwindow.hpp | 4 +++- apps/openmw/mwgui/windowmanagerimp.cpp | 7 +------ apps/openmw/mwgui/windowmanagerimp.hpp | 1 - 7 files changed, 16 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 4a346a14f..6c866fbc2 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -351,7 +351,6 @@ namespace MWBase virtual void writeFog(MWWorld::CellStore* cell) = 0; virtual const MWGui::TextColours& getTextColours() = 0; - virtual ToUTF8::FromType getEncoding() = 0; virtual bool injectKeyPress(MyGUI::KeyCode key, unsigned int text) = 0; }; } diff --git a/apps/openmw/mwgui/journalbooks.cpp b/apps/openmw/mwgui/journalbooks.cpp index 68b1d8403..07dacd0c2 100644 --- a/apps/openmw/mwgui/journalbooks.cpp +++ b/apps/openmw/mwgui/journalbooks.cpp @@ -156,8 +156,8 @@ MWGui::BookTypesetter::Utf8Span to_utf8_span (char const * text) typedef TypesetBook::Ptr book; -JournalBooks::JournalBooks (JournalViewModel::Ptr model) : - mModel (model) +JournalBooks::JournalBooks (JournalViewModel::Ptr model, ToUTF8::FromType encoding) : + mModel (model), mEncoding(encoding) { } @@ -220,8 +220,7 @@ book JournalBooks::createQuestBook (const std::string& questName) book JournalBooks::createTopicIndexBook () { - ToUTF8::FromType encoding = MWBase::Environment::get().getWindowManager()->getEncoding(); - bool isRussian = (encoding == ToUTF8::WINDOWS_1251); + bool isRussian = (mEncoding == ToUTF8::WINDOWS_1251); BookTypesetter::Ptr typesetter = isRussian ? createCyrillicJournalIndex() : createLatinJournalIndex(); diff --git a/apps/openmw/mwgui/journalbooks.hpp b/apps/openmw/mwgui/journalbooks.hpp index 769f05823..aa36eecdf 100644 --- a/apps/openmw/mwgui/journalbooks.hpp +++ b/apps/openmw/mwgui/journalbooks.hpp @@ -4,6 +4,8 @@ #include "bookpage.hpp" #include "journalviewmodel.hpp" +#include + namespace MWGui { MWGui::BookTypesetter::Utf8Span to_utf8_span (char const * text); @@ -13,7 +15,7 @@ namespace MWGui typedef TypesetBook::Ptr Book; JournalViewModel::Ptr mModel; - JournalBooks (JournalViewModel::Ptr model); + JournalBooks (JournalViewModel::Ptr model, ToUTF8::FromType encoding); Book createEmptyJournalBook (); Book createJournalBook (); @@ -22,6 +24,8 @@ namespace MWGui Book createQuestBook (const std::string& questName); Book createTopicIndexBook (); + ToUTF8::FromType mEncoding; + private: BookTypesetter::Ptr createTypesetter (); BookTypesetter::Ptr createLatinJournalIndex (); diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index 3c3205d91..a26f8d4ec 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -100,8 +100,8 @@ namespace return getWidget (name); } - JournalWindowImpl (MWGui::JournalViewModel::Ptr Model, bool questList) - : JournalBooks (Model), JournalWindow() + JournalWindowImpl (MWGui::JournalViewModel::Ptr Model, bool questList, ToUTF8::FromType encoding) + : JournalBooks (Model, encoding), JournalWindow() { center(); @@ -643,9 +643,9 @@ namespace } // glue the implementation to the interface -MWGui::JournalWindow * MWGui::JournalWindow::create (JournalViewModel::Ptr Model, bool questList) +MWGui::JournalWindow * MWGui::JournalWindow::create (JournalViewModel::Ptr Model, bool questList, ToUTF8::FromType encoding) { - return new JournalWindowImpl (Model, questList); + return new JournalWindowImpl (Model, questList, encoding); } MWGui::JournalWindow::JournalWindow() diff --git a/apps/openmw/mwgui/journalwindow.hpp b/apps/openmw/mwgui/journalwindow.hpp index c9bf0ef0a..62080f72e 100644 --- a/apps/openmw/mwgui/journalwindow.hpp +++ b/apps/openmw/mwgui/journalwindow.hpp @@ -3,6 +3,8 @@ #include "windowbase.hpp" +#include + #include namespace MWBase { class WindowManager; } @@ -16,7 +18,7 @@ namespace MWGui JournalWindow(); /// construct a new instance of the one JournalWindow implementation - static JournalWindow * create (std::shared_ptr Model, bool questList); + static JournalWindow * create (std::shared_ptr Model, bool questList, ToUTF8::FromType encoding); /// destroy this instance of the JournalWindow implementation virtual ~JournalWindow () {}; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index c302313f2..2084786b3 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -347,7 +347,7 @@ namespace MWGui mGuiModeStates[GM_Console] = GuiModeState(mConsole); bool questList = mResourceSystem->getVFS()->exists("textures/tx_menubook_options_over.dds"); - JournalWindow* journal = JournalWindow::create(JournalViewModel::create (), questList); + JournalWindow* journal = JournalWindow::create(JournalViewModel::create (), questList, mEncoding); mWindows.push_back(journal); mGuiModeStates[GM_Journal] = GuiModeState(journal); mGuiModeStates[GM_Journal].mCloseSound = "book close"; @@ -2034,11 +2034,6 @@ namespace MWGui return mTextColours; } - ToUTF8::FromType WindowManager::getEncoding() - { - return mEncoding; - } - bool WindowManager::injectKeyPress(MyGUI::KeyCode key, unsigned int text) { if (!mKeyboardNavigation->injectKeyPress(key, text)) diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index a264128b3..1d250f6d4 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -378,7 +378,6 @@ namespace MWGui void writeFog(MWWorld::CellStore* cell); virtual const MWGui::TextColours& getTextColours(); - virtual ToUTF8::FromType getEncoding(); virtual bool injectKeyPress(MyGUI::KeyCode key, unsigned int text); From 86a17b1e3ed68cab4114bb14ea8307774f646f12 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 22 Nov 2017 09:06:54 +0400 Subject: [PATCH 09/11] Get rid of the redundant Utf8Stream when during journal index creation --- apps/openmw/mwbase/windowmanager.hpp | 1 + apps/openmw/mwgui/journalbooks.cpp | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 6c866fbc2..f2b4a526d 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -351,6 +351,7 @@ namespace MWBase virtual void writeFog(MWWorld::CellStore* cell) = 0; virtual const MWGui::TextColours& getTextColours() = 0; + virtual bool injectKeyPress(MyGUI::KeyCode key, unsigned int text) = 0; }; } diff --git a/apps/openmw/mwgui/journalbooks.cpp b/apps/openmw/mwgui/journalbooks.cpp index 07dacd0c2..f3ee8162e 100644 --- a/apps/openmw/mwgui/journalbooks.cpp +++ b/apps/openmw/mwgui/journalbooks.cpp @@ -233,28 +233,26 @@ BookTypesetter::Ptr JournalBooks::createLatinJournalIndex () typesetter->setSectionAlignment (BookTypesetter::AlignCenter); + char ch = 'A'; + BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); for (int i = 0; i < 26; ++i) { - char ch = 'A' + i; char buffer [32]; sprintf (buffer, "( %c )", ch); - char buffer2 [32]; - sprintf(buffer2, "%c", ch); - Utf8Stream stream (buffer2); - uint32_t first = stream.peek(); - const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); BookTypesetter::Style* style = typesetter->createHotStyle (body, textColours.journalTopic, textColours.journalTopicOver, - textColours.journalTopicPressed, first); + textColours.journalTopicPressed, (uint32_t) ch); if (i == 13) typesetter->sectionBreak (); typesetter->write (style, to_utf8_span (buffer)); typesetter->lineBreak (); + + ch++; } return typesetter; @@ -267,15 +265,15 @@ BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex () typesetter->setSectionAlignment (BookTypesetter::AlignCenter); BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); + + unsigned char ch[2] = {0xd0, 0x90}; // CYRILLIC CAPITAL A is a 0xd090 in UTF-8 + for (int i = 0; i < 32; ++i) { char buffer [32]; - sprintf(buffer, "( %c%c )", 0xd0, 0x90 + i); // CYRILLIC CAPITAL A is a 0xd090 in UTF-8 + sprintf(buffer, "( %c%c )", ch[0], ch[1]); - char buffer2 [32]; - sprintf(buffer2, "%c%c", 0xd0, 0x90 + i); - - Utf8Stream stream (buffer2); + Utf8Stream stream ((char*) ch); uint32_t first = stream.peek(); const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); @@ -292,6 +290,8 @@ BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex () typesetter->write (style, to_utf8_span (buffer)); typesetter->lineBreak (); + + ch[1]++; } return typesetter; From a8bf4cdd98fea8bbb05925cc737c8c9e3eb3a63b Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 23 Nov 2017 19:29:40 +0400 Subject: [PATCH 10/11] Remove redundant include --- apps/openmw/mwbase/windowmanager.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index f2b4a526d..d454067c8 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -11,8 +11,6 @@ #include "../mwgui/mode.hpp" -#include - namespace Loading { class Listener; From 94c0e3ed10dd58b122ddecb4192b19365e8befe8 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 23 Nov 2017 19:37:45 +0400 Subject: [PATCH 11/11] Move toUpper() from StringUtils to the JournalViewModel --- apps/openmw/mwgui/journalviewmodel.cpp | 19 ++++++++++++++++++- components/misc/stringops.hpp | 18 ------------------ 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/apps/openmw/mwgui/journalviewmodel.cpp b/apps/openmw/mwgui/journalviewmodel.cpp index d7b233ff3..6ff68c9c5 100644 --- a/apps/openmw/mwgui/journalviewmodel.cpp +++ b/apps/openmw/mwgui/journalviewmodel.cpp @@ -314,7 +314,7 @@ struct JournalViewModelImpl : JournalViewModel for (MWBase::Journal::TTopicIter i = journal->topicBegin (); i != journal->topicEnd (); ++i) { Utf8Stream stream (i->first.c_str()); - uint32_t first = Misc::StringUtils::toUpper(stream.peek()); + uint32_t first = toUpper(stream.peek()); if (first != character) continue; @@ -323,6 +323,23 @@ struct JournalViewModelImpl : JournalViewModel } } + static uint32_t toUpper(uint32_t ch) + { + // Russian alphabet + if (ch >= 0x0430 && ch < 0x0450) + ch -= 0x20; + + // Cyrillic IO character + if (ch == 0x0451) + ch -= 0x50; + + // Latin alphabet + if (ch >= 0x61 && ch < 0x80) + ch -= 0x20; + + return ch; + } + struct TopicEntryImpl : BaseEntry { MWDialogue::Topic const & mTopic; diff --git a/components/misc/stringops.hpp b/components/misc/stringops.hpp index 1edb5ea61..9f4931d72 100644 --- a/components/misc/stringops.hpp +++ b/components/misc/stringops.hpp @@ -1,7 +1,6 @@ #ifndef MISC_STRINGOPS_H #define MISC_STRINGOPS_H -#include #include #include #include @@ -57,23 +56,6 @@ public: }; } - static uint32_t toUpper(uint32_t ch) - { - // Russian alphabet - if (ch >= 0x0430 && ch < 0x0450) - ch -= 0x20; - - // Cyrillic YO character - if (ch == 0x0451) - ch -= 0x50; - - // Latin alphabet - if (ch >= 0x61 && ch < 0x80) - ch -= 0x20; - - return ch; - } - static bool ciLess(const std::string &x, const std::string &y) { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end(), ci()); }