TachyonUI 0.1.0
High-performance UI for building tools.
Loading...
Searching...
No Matches
gui_utf8.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstddef>
4#include <cstdint>
5#include <string>
6#include <string_view>
7
8namespace tachyon
9{
12
13 inline constexpr uint32_t kInvalidCodepoint = 0xFFFFFFFFu;
14
17 inline uint32_t NextUtf8Codepoint(std::string_view text, size_t& i)
18 {
19 const auto lead = static_cast<unsigned char>(text[i]);
20 const int length = lead < 0x80 ? 1 : (lead >> 5) == 0x6 ? 2 : (lead >> 4) == 0xE ? 3 : (lead >> 3) == 0x1E ? 4 : 0;
21 if (length == 0 || i + size_t(length) > text.size())
22 {
23 i++;
24 return kInvalidCodepoint;
25 }
26 uint32_t codepoint = length == 1 ? lead : lead & (0x7Fu >> length);
27 for (int k = 1; k < length; ++k)
28 {
29 const auto next = static_cast<unsigned char>(text[i + size_t(k)]);
30 if ((next & 0xC0u) != 0x80u)
31 {
32 i++;
33 return kInvalidCodepoint;
34 }
35 codepoint = (codepoint << 6) | (next & 0x3Fu);
36 }
37 i += size_t(length);
38 return codepoint;
39 }
40
41 inline void AppendUtf8(std::string& out, uint32_t codepoint)
42 {
43 if (codepoint < 0x80) { out += char(codepoint); }
44 else if (codepoint < 0x800) { out += char(0xC0 | (codepoint >> 6)); out += char(0x80 | (codepoint & 0x3F)); }
45 else if (codepoint < 0x10000) { out += char(0xE0 | (codepoint >> 12)); out += char(0x80 | ((codepoint >> 6) & 0x3F)); out += char(0x80 | (codepoint & 0x3F)); }
46 else { out += char(0xF0 | (codepoint >> 18)); out += char(0x80 | ((codepoint >> 12) & 0x3F)); out += char(0x80 | ((codepoint >> 6) & 0x3F)); out += char(0x80 | (codepoint & 0x3F)); }
47 }
48
50 inline std::string ToValidUtf8(std::string_view text)
51 {
52 std::string valid;
53 valid.reserve(text.size());
54 for (size_t i = 0; i < text.size(); )
55 {
56 const size_t start = i;
57 const uint32_t codepoint = NextUtf8Codepoint(text, i);
58 if (codepoint == kInvalidCodepoint)
59 AppendUtf8(valid, 0xFFFD);
60 else
61 valid.append(text.substr(start, i - start));
62 }
63 return valid;
64 }
65
67 inline size_t LastUtf8CodepointSize(std::string_view text)
68 {
69 size_t size = 0;
70 while (size < text.size())
71 {
72 size++;
73 if ((static_cast<unsigned char>(text[text.size() - size]) & 0xC0u) != 0x80u)
74 break;
75 }
76 return size;
77 }
78
79}
std::string ToValidUtf8(std::string_view text)
text with each malformed byte replaced by U+FFFD (the replacement character).
Definition gui_utf8.h:50
void AppendUtf8(std::string &out, uint32_t codepoint)
Definition gui_utf8.h:41
size_t LastUtf8CodepointSize(std::string_view text)
The byte length of text's last codepoint (0 when empty).
Definition gui_utf8.h:67
constexpr uint32_t kInvalidCodepoint
Definition gui_utf8.h:13
uint32_t NextUtf8Codepoint(std::string_view text, size_t &i)
The codepoint starting at text[i], with i moved past it.
Definition gui_utf8.h:17
Definition gui_logging.h:24