summaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/enriched_string.cpp88
-rw-r--r--src/util/enriched_string.h28
-rw-r--r--src/util/string.cpp123
-rw-r--r--src/util/string.h19
4 files changed, 127 insertions, 131 deletions
diff --git a/src/util/enriched_string.cpp b/src/util/enriched_string.cpp
index 642188a52..762d094eb 100644
--- a/src/util/enriched_string.cpp
+++ b/src/util/enriched_string.cpp
@@ -19,7 +19,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "enriched_string.h"
#include "util/string.h"
+#include "debug.h"
#include "log.h"
+
using namespace irr::video;
EnrichedString::EnrichedString()
@@ -28,10 +30,12 @@ EnrichedString::EnrichedString()
}
EnrichedString::EnrichedString(const std::wstring &string,
- const std::vector<SColor> &colors):
- m_string(string),
- m_colors(colors)
-{}
+ const std::vector<SColor> &colors)
+{
+ clear();
+ m_string = string;
+ m_colors = colors;
+}
EnrichedString::EnrichedString(const std::wstring &s, const SColor &color)
{
@@ -45,15 +49,28 @@ EnrichedString::EnrichedString(const wchar_t *str, const SColor &color)
addAtEnd(translate_string(std::wstring(str)), color);
}
+void EnrichedString::clear()
+{
+ m_string.clear();
+ m_colors.clear();
+ m_has_background = false;
+ m_default_length = 0;
+ m_default_color = irr::video::SColor(255, 255, 255, 255);
+ m_background = irr::video::SColor(0, 0, 0, 0);
+}
+
void EnrichedString::operator=(const wchar_t *str)
{
clear();
- addAtEnd(translate_string(std::wstring(str)), SColor(255, 255, 255, 255));
+ addAtEnd(translate_string(std::wstring(str)), m_default_color);
}
void EnrichedString::addAtEnd(const std::wstring &s, const SColor &initial_color)
{
SColor color(initial_color);
+ bool use_default = (m_default_length == m_string.size() &&
+ color == m_default_color);
+
size_t i = 0;
while (i < s.length()) {
if (s[i] != L'\x1b') {
@@ -90,6 +107,12 @@ void EnrichedString::addAtEnd(const std::wstring &s, const SColor &initial_color
continue;
}
parseColorString(wide_to_utf8(parts[1]), color, true);
+
+ // No longer use default color after first escape
+ if (use_default) {
+ m_default_length = m_string.size();
+ use_default = false;
+ }
} else if (parts[0] == L"b") {
if (parts.size() < 2) {
continue;
@@ -98,6 +121,10 @@ void EnrichedString::addAtEnd(const std::wstring &s, const SColor &initial_color
m_has_background = true;
}
}
+
+ // Update if no escape character was found
+ if (use_default)
+ m_default_length = m_string.size();
}
void EnrichedString::addChar(const EnrichedString &source, size_t i)
@@ -110,7 +137,7 @@ void EnrichedString::addCharNoColor(wchar_t c)
{
m_string += c;
if (m_colors.empty()) {
- m_colors.emplace_back(255, 255, 255, 255);
+ m_colors.emplace_back(m_default_color);
} else {
m_colors.push_back(m_colors[m_colors.size() - 1]);
}
@@ -118,35 +145,44 @@ void EnrichedString::addCharNoColor(wchar_t c)
EnrichedString EnrichedString::operator+(const EnrichedString &other) const
{
- std::vector<SColor> result;
- result.insert(result.end(), m_colors.begin(), m_colors.end());
- result.insert(result.end(), other.m_colors.begin(), other.m_colors.end());
- return EnrichedString(m_string + other.m_string, result);
+ EnrichedString result = *this;
+ result += other;
+ return result;
}
void EnrichedString::operator+=(const EnrichedString &other)
{
+ bool update_default_color = m_default_length == m_string.size();
+
m_string += other.m_string;
m_colors.insert(m_colors.end(), other.m_colors.begin(), other.m_colors.end());
+
+ if (update_default_color) {
+ m_default_length += other.m_default_length;
+ updateDefaultColor();
+ }
}
EnrichedString EnrichedString::substr(size_t pos, size_t len) const
{
- if (pos == m_string.length()) {
+ if (pos >= m_string.length())
return EnrichedString();
- }
- if (len == std::string::npos || pos + len > m_string.length()) {
- return EnrichedString(
- m_string.substr(pos, std::string::npos),
- std::vector<SColor>(m_colors.begin() + pos, m_colors.end())
- );
- }
- return EnrichedString(
+ if (len == std::string::npos || pos + len > m_string.length())
+ len = m_string.length() - pos;
+
+ EnrichedString str(
m_string.substr(pos, len),
std::vector<SColor>(m_colors.begin() + pos, m_colors.begin() + pos + len)
);
+ str.m_has_background = m_has_background;
+ str.m_background = m_background;
+
+ if (pos < m_default_length)
+ str.m_default_length = std::min(m_default_length - pos, str.size());
+ str.setDefaultColor(m_default_color);
+ return str;
}
const wchar_t *EnrichedString::c_str() const
@@ -163,3 +199,17 @@ const std::wstring &EnrichedString::getString() const
{
return m_string;
}
+
+void EnrichedString::setDefaultColor(const irr::video::SColor &color)
+{
+ m_default_color = color;
+ updateDefaultColor();
+}
+
+void EnrichedString::updateDefaultColor()
+{
+ sanity_check(m_default_length <= m_colors.size());
+
+ for (size_t i = 0; i < m_default_length; ++i)
+ m_colors[i] = m_default_color;
+}
diff --git a/src/util/enriched_string.h b/src/util/enriched_string.h
index 202d84cb0..c8a095887 100644
--- a/src/util/enriched_string.h
+++ b/src/util/enriched_string.h
@@ -32,6 +32,7 @@ public:
const irr::video::SColor &color = irr::video::SColor(255, 255, 255, 255));
EnrichedString(const std::wstring &string,
const std::vector<irr::video::SColor> &colors);
+ void clear();
void operator=(const wchar_t *str);
void addAtEnd(const std::wstring &s, const irr::video::SColor &color);
@@ -50,6 +51,14 @@ public:
const wchar_t *c_str() const;
const std::vector<irr::video::SColor> &getColors() const;
const std::wstring &getString() const;
+
+ void setDefaultColor(const irr::video::SColor &color);
+ void updateDefaultColor();
+ inline const irr::video::SColor &getDefaultColor() const
+ {
+ return m_default_color;
+ }
+
inline bool operator==(const EnrichedString &other) const
{
return (m_string == other.m_string && m_colors == other.m_colors);
@@ -58,12 +67,6 @@ public:
{
return !(*this == other);
}
- inline void clear()
- {
- m_string.clear();
- m_colors.clear();
- m_has_background = false;
- }
inline bool empty() const
{
return m_string.empty();
@@ -72,6 +75,7 @@ public:
{
return m_string.size();
}
+
inline bool hasBackground() const
{
return m_has_background;
@@ -80,9 +84,19 @@ public:
{
return m_background;
}
+ inline void setBackground(const irr::video::SColor &color)
+ {
+ m_background = color;
+ m_has_background = true;
+ }
+
private:
std::wstring m_string;
std::vector<irr::video::SColor> m_colors;
- bool m_has_background = false;
+ bool m_has_background;
+ irr::video::SColor m_default_color;
irr::video::SColor m_background;
+ // This variable defines the length of the default-colored text.
+ // Change this to a std::vector if an "end coloring" tag is wanted.
+ size_t m_default_length = 0;
};
diff --git a/src/util/string.cpp b/src/util/string.cpp
index 388e8d293..e6c52585d 100644
--- a/src/util/string.cpp
+++ b/src/util/string.cpp
@@ -79,6 +79,13 @@ bool convert(const char *to, const char *from, char *outbuf,
return true;
}
+#ifdef __ANDROID__
+// Android need manual caring to support the full character set possible with wchar_t
+const char *DEFAULT_ENCODING = "UTF-32LE";
+#else
+const char *DEFAULT_ENCODING = "WCHAR_T";
+#endif
+
std::wstring utf8_to_wide(const std::string &input)
{
size_t inbuf_size = input.length() + 1;
@@ -90,7 +97,12 @@ std::wstring utf8_to_wide(const std::string &input)
char *outbuf = new char[outbuf_size];
memset(outbuf, 0, outbuf_size);
- if (!convert("WCHAR_T", "UTF-8", outbuf, outbuf_size, inbuf, inbuf_size)) {
+#ifdef __ANDROID__
+ // Android need manual caring to support the full character set possible with wchar_t
+ SANITY_CHECK(sizeof(wchar_t) == 4);
+#endif
+
+ if (!convert(DEFAULT_ENCODING, "UTF-8", outbuf, outbuf_size, inbuf, inbuf_size)) {
infostream << "Couldn't convert UTF-8 string 0x" << hex_encode(input)
<< " into wstring" << std::endl;
delete[] inbuf;
@@ -105,13 +117,6 @@ std::wstring utf8_to_wide(const std::string &input)
return out;
}
-#ifdef __ANDROID__
-// TODO: this is an ugly fix for wide_to_utf8 somehow not working on android
-std::string wide_to_utf8(const std::wstring &input)
-{
- return wide_to_narrow(input);
-}
-#else
std::string wide_to_utf8(const std::wstring &input)
{
size_t inbuf_size = (input.length() + 1) * sizeof(wchar_t);
@@ -123,7 +128,7 @@ std::string wide_to_utf8(const std::wstring &input)
char *outbuf = new char[outbuf_size];
memset(outbuf, 0, outbuf_size);
- if (!convert("UTF-8", "WCHAR_T", outbuf, outbuf_size, inbuf, inbuf_size)) {
+ if (!convert("UTF-8", DEFAULT_ENCODING, outbuf, outbuf_size, inbuf, inbuf_size)) {
infostream << "Couldn't convert wstring 0x" << hex_encode(inbuf, inbuf_size)
<< " into UTF-8 string" << std::endl;
delete[] inbuf;
@@ -138,7 +143,6 @@ std::string wide_to_utf8(const std::wstring &input)
return out;
}
-#endif
#else // _WIN32
std::wstring utf8_to_wide(const std::string &input)
@@ -183,7 +187,7 @@ wchar_t *utf8_to_wide_c(const char *str)
// The returned string is allocated using new
wchar_t *narrow_to_wide_c(const char *str)
{
- wchar_t *nstr = NULL;
+ wchar_t *nstr = nullptr;
#if defined(_WIN32)
int nResult = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) str, -1, 0, 0);
if (nResult == 0) {
@@ -204,67 +208,8 @@ wchar_t *narrow_to_wide_c(const char *str)
return nstr;
}
-
-#ifdef __ANDROID__
-
-const wchar_t* wide_chars =
- L" !\"#$%&'()*+,-./0123456789:;<=>?@"
- L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`"
- L"abcdefghijklmnopqrstuvwxyz{|}~";
-
-int wctomb(char *s, wchar_t wc)
-{
- for (unsigned int j = 0; j < (sizeof(wide_chars)/sizeof(wchar_t));j++) {
- if (wc == wide_chars[j]) {
- *s = (char) (j+32);
- return 1;
- }
- else if (wc == L'\n') {
- *s = '\n';
- return 1;
- }
- }
- return -1;
-}
-
-int mbtowc(wchar_t *pwc, const char *s, size_t n)
-{
- std::wstring intermediate = narrow_to_wide(s);
-
- if (intermediate.length() > 0) {
- *pwc = intermediate[0];
- return 1;
- }
- else {
- return -1;
- }
-}
-
std::wstring narrow_to_wide(const std::string &mbs) {
size_t wcl = mbs.size();
-
- std::wstring retval = L"";
-
- for (unsigned int i = 0; i < wcl; i++) {
- if (((unsigned char) mbs[i] >31) &&
- ((unsigned char) mbs[i] < 127)) {
-
- retval += wide_chars[(unsigned char) mbs[i] -32];
- }
- //handle newline
- else if (mbs[i] == '\n') {
- retval += L'\n';
- }
- }
-
- return retval;
-}
-
-#else // not Android
-
-std::wstring narrow_to_wide(const std::string &mbs)
-{
- size_t wcl = mbs.size();
Buffer<wchar_t> wcs(wcl + 1);
size_t len = mbstowcs(*wcs, mbs.c_str(), wcl);
if (len == (size_t)(-1))
@@ -273,37 +218,6 @@ std::wstring narrow_to_wide(const std::string &mbs)
return *wcs;
}
-#endif
-
-#ifdef __ANDROID__
-
-std::string wide_to_narrow(const std::wstring &wcs) {
- size_t mbl = wcs.size()*4;
-
- std::string retval = "";
- for (unsigned int i = 0; i < wcs.size(); i++) {
- wchar_t char1 = (wchar_t) wcs[i];
-
- if (char1 == L'\n') {
- retval += '\n';
- continue;
- }
-
- for (unsigned int j = 0; j < wcslen(wide_chars);j++) {
- wchar_t char2 = (wchar_t) wide_chars[j];
-
- if (char1 == char2) {
- char toadd = (j+32);
- retval += toadd;
- break;
- }
- }
- }
-
- return retval;
-}
-
-#else // not Android
std::string wide_to_narrow(const std::wstring &wcs)
{
@@ -317,7 +231,6 @@ std::string wide_to_narrow(const std::wstring &wcs)
return *mbs;
}
-#endif
std::string urlencode(const std::string &str)
{
@@ -361,10 +274,10 @@ u32 readFlagString(std::string str, const FlagDesc *flagdesc, u32 *flagmask)
u32 mask = 0;
char *s = &str[0];
char *flagstr;
- char *strpos = NULL;
+ char *strpos = nullptr;
while ((flagstr = strtok_r(s, ",", &strpos))) {
- s = NULL;
+ s = nullptr;
while (*flagstr == ' ' || *flagstr == '\t')
flagstr++;
@@ -436,7 +349,7 @@ char *mystrtok_r(char *s, const char *sep, char **lasts)
s++;
if (!*s)
- return NULL;
+ return nullptr;
t = s;
while (*t) {
diff --git a/src/util/string.h b/src/util/string.h
index ab9a4a6c8..0d2a6bdb2 100644
--- a/src/util/string.h
+++ b/src/util/string.h
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once
#include "irrlichttypes_bloated.h"
+#include "irrString.h"
#include <cstdlib>
#include <string>
#include <cstring>
@@ -723,3 +724,21 @@ inline std::string str_join(const std::vector<std::string> &list,
}
return oss.str();
}
+
+/**
+ * Create a UTF8 std::string from a irr::core::stringw.
+ */
+inline std::string stringw_to_utf8(const irr::core::stringw &input)
+{
+ std::wstring str(input.c_str());
+ return wide_to_utf8(str);
+}
+
+ /**
+ * Create a irr::core:stringw from a UTF8 std::string.
+ */
+inline irr::core::stringw utf8_to_stringw(const std::string &input)
+{
+ std::wstring str = utf8_to_wide(input);
+ return irr::core::stringw(str.c_str());
+}