diff --git a/nel/include/nel/gui/string_case.h b/nel/include/nel/gui/string_case.h index ec8fa2925..300d72c76 100644 --- a/nel/include/nel/gui/string_case.h +++ b/nel/include/nel/gui/string_case.h @@ -39,6 +39,7 @@ namespace NLGUI void setCase( ucstring &str, TCaseMode mode ); + void setCase( std::string &str, TCaseMode mode ); } diff --git a/nel/include/nel/misc/common.h b/nel/include/nel/misc/common.h index a5d1b2f27..7b89bae3b 100644 --- a/nel/include/nel/misc/common.h +++ b/nel/include/nel/misc/common.h @@ -227,17 +227,18 @@ inline double isValidDouble (double v) * \param str a string to transform to lower case */ -std::string toLower ( const char *str ); -std::string toLower ( const std::string &str ); -void toLower ( char *str ); +std::string toLower ( const char *str ); // UTF-8 +std::string toLower ( const std::string &str ); // UTF-8 +void toLower ( char *str ); // Ascii only char toLower ( const char ch ); // convert only one character /** Convert a string in upper case. * \param a string to transform to upper case */ -std::string toUpper ( const std::string &str); -void toUpper ( char *str); +std::string toUpper ( const char *str ); // UTF-8 +std::string toUpper ( const std::string &str); // UTF-8 +void toUpper ( char *str); // Ascii only /** diff --git a/nel/src/gui/string_case.cpp b/nel/src/gui/string_case.cpp index c96e2cc7f..f6218d39a 100644 --- a/nel/src/gui/string_case.cpp +++ b/nel/src/gui/string_case.cpp @@ -19,6 +19,7 @@ #include "stdpch.h" #include "nel/gui/string_case.h" +#include "nel/misc/utf_string_view.h" #ifdef DEBUG_NEW #define new DEBUG_NEW @@ -26,13 +27,33 @@ namespace NLGUI { + inline bool isSeparator (u32char c) + { + return (c == (u32char)' ') || (c == (u32char)'\t') || (c == (u32char)'\n') || (c == (u32char)'\r'); + } + inline bool isSeparator (ucchar c) { return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'); } + inline bool isSeparator (char c) + { + return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'); + } + // *************************************************************************** + inline bool isEndSentence (u32char c, u32char lastChar) + { + // Ex: One sentence. Another sentence. + // ^ + // Counterexample: nevrax.com + // ^ + return ((c == (u32char)' ') || (c == (u32char)'\n')) + && (lastChar == (u32char)'.') || (lastChar == (u32char)'!') || (lastChar == (u32char)'?'); + } + inline bool isEndSentence (ucstring& str, uint index) { // Ex: One sentence. Another sentence. @@ -117,6 +138,109 @@ namespace NLGUI } } + void setCase(std::string &str, TCaseMode mode) + { + const uint length = (uint)str.length(); + uint i; + bool newString = true; + bool newSentence = true; + bool newWord = true; + switch (mode) + { + case CaseLower: + str = NLMISC::toLower(str); + break; + case CaseUpper: + str = NLMISC::toUpper(str); + break; + case CaseFirstStringLetterUp: + { + NLMISC::CUtfStringView sv(str); + std::string res; + res.reserve(sv.largestSize()); + for (NLMISC::CUtfStringView::iterator it(sv.begin()), end(sv.end()); it != end; ++it) + { + u32char c = *it; + if (c < 0x10000) + { + if (!isSeparator(c)) + { + if (newString) + c = NLMISC::toUpper((ucchar)c); + else + c = NLMISC::toLower((ucchar)c); + newString = false; + } + } + NLMISC::CUtfStringView::append(res, c); + } + str = nlmove(res); + break; + } + case CaseFirstSentenceLetterUp: + { + NLMISC::CUtfStringView sv(str); + std::string res; + res.reserve(sv.largestSize()); + u32char lastChar = 0; + for (NLMISC::CUtfStringView::iterator it(sv.begin()), end(sv.end()); it != end; ++it) + { + u32char c = *it; + if (c < 0x10000) + { + if (isEndSentence(c, lastChar)) + newSentence = true; + else + { + if (newSentence) + c = NLMISC::toUpper((ucchar)c); + else + c = NLMISC::toLower((ucchar)c); + + if (!isSeparator(c)) + newSentence = false; + } + } + NLMISC::CUtfStringView::append(res, c); + lastChar = c; + } + str = nlmove(res); + break; + } + case CaseFirstWordLetterUp: + { + NLMISC::CUtfStringView sv(str); + std::string res; + res.reserve(sv.largestSize()); + u32char lastChar = 0; + for (NLMISC::CUtfStringView::iterator it(sv.begin()), end(sv.end()); it != end; ++it) + { + u32char c = *it; + if (c < 0x10000) + { + if (isSeparator(c) || isEndSentence(c, lastChar)) + newWord = true; + else + { + if (newWord) + c = NLMISC::toUpper((ucchar)c); + else + c = NLMISC::toLower((ucchar)c); + + newWord = false; + } + } + NLMISC::CUtfStringView::append(res, c); + lastChar = c; + } + str = nlmove(res); + break; + } + default: + break; + } + } + } diff --git a/nel/src/misc/common.cpp b/nel/src/misc/common.cpp index b9e9a7d85..c1bf67efa 100644 --- a/nel/src/misc/common.cpp +++ b/nel/src/misc/common.cpp @@ -594,6 +594,7 @@ NLMISC_CATEGORISED_COMMAND(nel,stohr, "Convert a second number into an human rea return true; } +/* std::string toLower(const char *str) { if (!str) return ""; @@ -624,6 +625,7 @@ std::string toLower(const std::string &str) } return res; } +*/ char toLower(const char ch) { @@ -652,6 +654,7 @@ void toLower(char *str) } } +/* std::string toUpper(const std::string &str) { string res; @@ -665,6 +668,7 @@ std::string toUpper(const std::string &str) } return res; } +*/ void toUpper(char *str) { diff --git a/nel/src/misc/unicode.cpp b/nel/src/misc/unicode.cpp index 47a4cdfde..12dfdcad4 100644 --- a/nel/src/misc/unicode.cpp +++ b/nel/src/misc/unicode.cpp @@ -16,6 +16,7 @@ #include "stdmisc.h" #include "nel/misc/ucstring.h" +#include "nel/misc/utf_string_view.h" #ifdef DEBUG_NEW #define new DEBUG_NEW @@ -1949,6 +1950,39 @@ ucchar toLower (ucchar c) // *************************************************************************** +static std::string toLower(CUtfStringView sv) +{ + std::string res; + res.reserve(sv.largestSize()); + for (CUtfStringView::iterator it(sv.begin()), end(sv.end()); it != end; ++it) + { + u32char c = *it; + if (c < 0x10000) + { + ucchar uc = c; + ucchar *result = toLowerUpperSearch(&uc, UnicodeUpperToLower); + if (result) + c = uc; + } + CUtfStringView::append(res, c); + } + return res; +} + +std::string toLower(const char *str) +{ + return toLower(CUtfStringView(str)); +} + +// *************************************************************************** + +std::string toLower(const std::string &str) +{ + return toLower(CUtfStringView(str)); +} + +// *************************************************************************** + ucstring toUpper (const ucstring &str) { uint i; @@ -1991,4 +2025,37 @@ ucchar toUpper (ucchar c) // *************************************************************************** +static std::string toUpper(CUtfStringView sv) +{ + std::string res; + res.reserve(sv.largestSize()); + for (CUtfStringView::iterator it(sv.begin()), end(sv.end()); it != end; ++it) + { + u32char c = *it; + if (c < 0x10000) + { + ucchar uc = c; + ucchar *result = toLowerUpperSearch(&uc, UnicodeLowerToUpper); + if (result) + c = uc; + } + CUtfStringView::append(res, c); + } + return res; +} + +std::string toUpper(const char *str) +{ + return toUpper(CUtfStringView(str)); +} + +// *************************************************************************** + +std::string toUpper(const std::string &str) +{ + return toUpper(CUtfStringView(str)); +} + +// *************************************************************************** + } // NLMISC