29#include <TGUI/Config.hpp>
37#if defined TGUI_SYSTEM_WINDOWS && defined _MSC_VER
39 #pragma warning(disable:4127)
51 template <
typename CharT>
52 void encodeCharUtf8(
char32_t input, std::basic_string<CharT>& outStrUtf8)
56 outStrUtf8.push_back(
static_cast<CharT
>(input));
61 if ((input > 0x0010FFFF) || ((input >= 0xD800) && (input <= 0xDBFF)))
65 std::size_t bytestoWrite;
68 else if (input < 0x10000)
70 else if (input <= 0x0010FFFF)
75 static const std::uint8_t firstByteMask[5] = { 0, 0, 0xC0, 0xE0, 0xF0 };
78 std::array<CharT, 4> bytes;
79 if (bytestoWrite == 4) { bytes[3] =
static_cast<CharT
>((input | 0x80) & 0xBF); input >>= 6; }
80 if (bytestoWrite >= 3) { bytes[2] =
static_cast<CharT
>((input | 0x80) & 0xBF); input >>= 6; }
81 if (bytestoWrite >= 2) { bytes[1] =
static_cast<CharT
>((input | 0x80) & 0xBF); input >>= 6; }
82 if (bytestoWrite >= 1) { bytes[0] =
static_cast<CharT
>(input | firstByteMask[bytestoWrite]); }
85 outStrUtf8.append(bytes.begin(), bytes.begin() + bytestoWrite);
96 template <
typename CharIt>
97 CharIt decodeCharUtf8(CharIt inputCharIt, CharIt inputEndIt, std::u32string& outStrUtf32)
99 if (
static_cast<std::uint8_t
>(*inputCharIt) < 128)
101 outStrUtf32.push_back(
static_cast<char32_t>(
static_cast<std::uint8_t
>(*inputCharIt)));
102 return ++inputCharIt;
106 static const std::uint32_t offsetsMap[6] = { 0x00000000, 0x00003080, 0x000E2080, 0x03C82080, 0xFA082080, 0x82082080 };
107 static const std::uint8_t trailingMap[128] =
109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
112 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5
116 const std::uint8_t trailingBytes = trailingMap[
static_cast<std::uint8_t
>(*inputCharIt) - 128];
117 const std::uint32_t offset = offsetsMap[trailingBytes];
118 const auto remainingBytes = std::distance(inputCharIt, inputEndIt) - 1;
119 if (remainingBytes >=
static_cast<decltype(remainingBytes)
>(trailingBytes))
121 char32_t outputChar = 0;
122 for (std::uint8_t i = 0; i < trailingBytes; ++i)
124 outputChar +=
static_cast<char32_t>(
static_cast<std::uint8_t
>(*inputCharIt++));
128 outputChar +=
static_cast<char32_t>(
static_cast<std::uint8_t
>(*inputCharIt++));
129 outputChar -= offset;
130 outStrUtf32.push_back(outputChar);
133 inputCharIt = inputEndIt;
139#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201811L)
145 inline std::u8string convertUtf32toUtf8(
const std::u32string& strUtf32)
147 std::u8string outStrUtf8;
148 outStrUtf8.reserve(strUtf32.length() + 1);
149 for (
const char32_t& codepoint : strUtf32)
150 encodeCharUtf8(codepoint, outStrUtf8);
162 template <
typename CharIt>
163 std::u32string convertUtf8toUtf32(CharIt inputBegin, CharIt inputEnd)
165 std::u32string outStrUtf32;
166 outStrUtf32.reserve((inputEnd - inputBegin) + 1);
168 auto it = inputBegin;
169 while (it < inputEnd)
170 it = decodeCharUtf8(it, inputEnd, outStrUtf32);
182 template <
typename U16CharIt>
183 std::u32string convertUtf16toUtf32(U16CharIt inputBegin, U16CharIt inputEnd)
185 std::u32string outStrUtf32;
186 outStrUtf32.reserve((inputEnd - inputBegin) + 1);
188 auto it = inputBegin;
189 while (it < inputEnd)
191 const char16_t first = *it++;
194 if ((first < 0xD800) || (first > 0xDBFF))
196 outStrUtf32.push_back(
static_cast<char32_t>(first));
204 const char16_t second = *it++;
205 if ((second >= 0xDC00) && (second <= 0xDFFF))
206 outStrUtf32.push_back(((
static_cast<char32_t>(first) - 0xD800) << 10) + (
static_cast<char32_t>(second) - 0xDC00) + 0x0010000);
219 template <
typename WCharIt>
220 std::u32string convertWidetoUtf32(WCharIt inputBegin, WCharIt inputEnd)
222 std::u32string outStrUtf32;
223 outStrUtf32.reserve((inputEnd - inputBegin) + 1);
226 for (
auto it = inputBegin; it != inputEnd; ++it)
227 outStrUtf32.push_back(
static_cast<char32_t>(*it));
239 inline std::string convertUtf32toLatin1(
const std::u32string& strUtf32)
242 outStr.reserve(strUtf32.length() + 1);
243 for (
const char32_t codepoint : strUtf32)
246 outStr.push_back(
static_cast<char>(codepoint));
258 inline std::string convertUtf32toStdStringUtf8(
const std::u32string& strUtf32)
260 std::string outStrUtf8;
261 outStrUtf8.reserve(strUtf32.length() + 1);
262 for (
const char32_t codepoint : strUtf32)
263 encodeCharUtf8(codepoint, outStrUtf8);
274 inline std::wstring convertUtf32toWide(
const std::u32string& strUtf32)
277 outStr.reserve(strUtf32.length() + 1);
279#if defined(__cpp_if_constexpr) && (__cpp_if_constexpr >= 201606L)
280 if constexpr (
sizeof(wchar_t) == 4)
282 if (
sizeof(
wchar_t) == 4)
286 for (
const char32_t codepoint : strUtf32)
287 outStr.push_back(
static_cast<wchar_t>(codepoint));
292 for (
const char32_t codepoint : strUtf32)
294 if ((codepoint < 0xD800) || ((codepoint > 0xDFFF) && (codepoint <= 0xFFFF)))
295 outStr.push_back(
static_cast<wchar_t>(codepoint));
308 inline std::u16string convertUtf32toUtf16(
const std::u32string& strUtf32)
310 std::u16string outStrUtf16;
311 outStrUtf16.reserve(strUtf32.length() + 1);
313 for (
const char32_t codepoint : strUtf32)
316 if (codepoint <= 0xFFFF)
318 if ((codepoint < 0xD800) || (codepoint > 0xDFFF))
319 outStrUtf16.push_back(
static_cast<char16_t>(codepoint));
323 else if (codepoint > 0x0010FFFF)
327 outStrUtf16.push_back(
static_cast<char16_t>(((codepoint - 0x0010000) >> 10) + 0xD800));
328 outStrUtf16.push_back(
static_cast<char16_t>(((codepoint - 0x0010000) & 0x3FFUL) + 0xDC00));
338#if defined TGUI_SYSTEM_WINDOWS && defined _MSC_VER
Namespace that contains all TGUI functions and classes.
Definition: AbsoluteOrRelativeValue.hpp:36