From ba91cd658b019dbf1ee93c4185333687c3e086a7 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 21 Nov 2017 12:31:23 +0400 Subject: [PATCH] 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]; + 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()); - std::pair symbol = Misc::StringUtils::toLower(byte1, byte2); + if (first != character) + continue; - // 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 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/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; - return symbol; + // Cyrillic YO character + if (ch == 0x0451) + ch -= 0x50; + + // Latin alphabete + if (ch >= 0x61 && ch < 0x80) + ch -= 0x20; + + return ch; } static bool ciLess(const std::string &x, const std::string &y) {