33struct WordBreakPropertyInterval {
45constexpr auto g_extend_characters{[]()
constexpr {
47 constexpr size_t size = []()
constexpr {
50 if (interval.property == WBP::Extend) {
58 std::array<Interval, size> result{};
61 if (interval.property == WBP::Extend) {
62 result[index++] = {interval.first, interval.last};
70bool Bisearch(uint32_t ucs,
const std::array<Interval, N>& table) {
71 if (ucs < table.front().first || ucs > table.back().last) {
78 const int mid = (min + max) / 2;
79 if (ucs > table[mid].last) {
81 }
else if (ucs < table[mid].first) {
92template <
class C,
size_t N>
93bool Bisearch(uint32_t ucs,
const std::array<C, N>& table, C* out) {
94 if (ucs < table.front().first || ucs > table.back().last) {
101 const int mid = (min + max) / 2;
102 if (ucs > table[mid].last) {
104 }
else if (ucs < table[mid].first) {
115int codepoint_width(uint32_t ucs) {
143 if (start >= input.size()) {
147 const uint8_t C0 = input[start];
150 if ((C0 & 0b1000'0000) == 0b0000'0000) {
151 *ucs = C0 & 0b0111'1111;
157 if ((C0 & 0b1110'0000) == 0b1100'0000 &&
158 start + 1 < input.size()) {
159 const uint8_t C1 = input[start + 1];
161 *ucs += C0 & 0b0001'1111;
163 *ucs += C1 & 0b0011'1111;
169 if ((C0 & 0b1111'0000) == 0b1110'0000 &&
170 start + 2 < input.size()) {
171 const uint8_t C1 = input[start + 1];
172 const uint8_t C2 = input[start + 2];
174 *ucs += C0 & 0b0000'1111;
176 *ucs += C1 & 0b0011'1111;
178 *ucs += C2 & 0b0011'1111;
184 if ((C0 & 0b1111'1000) == 0b1111'0000 &&
185 start + 3 < input.size()) {
186 const uint8_t C1 = input[start + 1];
187 const uint8_t C2 = input[start + 2];
188 const uint8_t C3 = input[start + 3];
190 *ucs += C0 & 0b0000'0111;
192 *ucs += C1 & 0b0011'1111;
194 *ucs += C2 & 0b0011'1111;
196 *ucs += C3 & 0b0011'1111;
213 if (start >= input.size()) {
219 if constexpr (
sizeof(wchar_t) == 4) {
226 int32_t C0 = input[start];
229 if (C0 < 0xd800 || C0 >= 0xdc00) {
236 if (start + 1 >= input.size()) {
241 int32_t C1 = input[start + 1];
242 *ucs = ((C0 & 0x3ff) << 10) + (C1 & 0x3ff) + 0x10000;
248 return Bisearch(ucs, g_extend_characters);
264 const uint32_t LINE_FEED = 10;
265 return ucs != LINE_FEED;
267 if (ucs >= 0x7f && ucs < 0xa0) {
274 WordBreakPropertyInterval interval = {0, 0, WBP::ALetter};
276 return interval.property;
280 return codepoint_width(uint32_t(ucs));
286 for (
const wchar_t& it : text) {
305 if (input.size() == 1) {
306 const char c = input[0];
307 if (c >= 32 && c < 127) {
315 bool is_pure_ascii =
true;
316 for (
const char c : input) {
317 if (c < 31 || c >= 127) {
318 is_pure_ascii =
false;
323 return static_cast<int>(input.size());
328 while (start < input.size()) {
329 uint32_t codepoint = 0;
353 std::vector<std::string> out;
354 out.reserve(input.size());
357 while (start < input.size()) {
358 uint32_t codepoint = 0;
364 const auto append = input.substr(start, end - start);
376 out.back() += append;
385 out.emplace_back(append);
386 out.emplace_back(
"");
391 out.emplace_back(append);
404 if ((input[start] & 0b1100'0000) == 0b1000'0000) {
408 uint32_t codepoint = 0;
410 const bool eaten =
EatCodePoint(input, start, &end, &codepoint);
422 bool glyph_found =
false;
423 while (start < input.size()) {
425 uint32_t codepoint = 0;
426 const bool eaten =
EatCodePoint(input, start, &end, &codepoint);
437 return static_cast<int>(start);
444 return static_cast<int>(input.size());
447size_t GlyphIterate(std::string_view input,
int glyph_offset,
size_t start) {
448 if (glyph_offset >= 0) {
449 for (
int i = 0; i < glyph_offset; ++i) {
454 for (
int i = 0; i < -glyph_offset; ++i) {
463 std::vector<int> out;
464 out.reserve(input.size());
467 while (start < input.size()) {
468 uint32_t codepoint = 0;
469 const bool eaten =
EatCodePoint(input, start, &end, &codepoint);
508 while (start < input.size()) {
509 uint32_t codepoint = 0;
510 const bool eaten =
EatCodePoint(input, start, &end, &codepoint);
533 std::vector<WordBreakProperty> out;
534 out.reserve(input.size());
537 while (start < input.size()) {
538 uint32_t codepoint = 0;
555 WordBreakPropertyInterval interval = {0, 0, WBP::ALetter};
557 out.push_back(interval.property);
567 uint32_t codepoint = 0;
584 if (codepoint <= 0b000'0000'0111'1111) {
585 const uint8_t p1 = codepoint;
591 if (codepoint <= 0b000'0111'1111'1111) {
592 uint8_t p2 = codepoint & 0b111111;
594 uint8_t p1 = codepoint;
595 out.push_back(0b11000000 + p1);
596 out.push_back(0b10000000 + p2);
601 if (codepoint <= 0b1111'1111'1111'1111) {
602 uint8_t p3 = codepoint & 0b111111;
604 uint8_t p2 = codepoint & 0b111111;
606 uint8_t p1 = codepoint;
607 out.push_back(0b11100000 + p1);
608 out.push_back(0b10000000 + p2);
609 out.push_back(0b10000000 + p3);
614 if (codepoint <= 0b1'0000'1111'1111'1111'1111) {
615 uint8_t p4 = codepoint & 0b111111;
617 uint8_t p3 = codepoint & 0b111111;
619 uint8_t p2 = codepoint & 0b111111;
621 uint8_t p1 = codepoint;
622 out.push_back(0b11110000 + p1);
623 out.push_back(0b10000000 + p2);
624 out.push_back(0b10000000 + p3);
625 out.push_back(0b10000000 + p4);
639 uint32_t codepoint = 0;
642 if constexpr (
sizeof(wchar_t) == 4) {
643 out.push_back(codepoint);
651 if (codepoint < 0xD800 || (codepoint > 0xDFFF && codepoint < 0x10000)) {
652 uint16_t p0 = codepoint;
658 codepoint -= 0x010000;
659 uint16_t p0 = (((codepoint << 12) >> 22) + 0xD800);
660 uint16_t p1 = (((codepoint << 22) >> 22) + 0xDC00);
Decorator size(WidthOrHeight direction, Constraint constraint, int value)
Applique une contrainte sur la taille d'un élément.
L'espace de noms FTXUI ftxui::
bool IsControl(uint32_t ucs)
WordBreakProperty CodepointToWordBreakProperty(uint32_t codepoint)
size_t GlyphPrevious(std::string_view input, size_t start)
FTXUI_EXPORT(SCREEN) int string_width(std std::vector< std::string > Utf8ToGlyphs(std::string_view input)
int string_width(std::string_view input)
bool IsCombining(uint32_t ucs)
int wchar_width(wchar_t ucs)
bool EatCodePoint(std::string_view input, size_t start, size_t *end, uint32_t *ucs)
std::string to_string(std::wstring_view s)
Convertit un std::wstring en std::string UTF8.
int GlyphCount(std::string_view input)
std::vector< WordBreakProperty > Utf8ToWordBreakProperty(std::string_view input)
int wstring_width(const std::wstring &text)
std::vector< int > CellToGlyphIndex(std::string_view input)
FTXUI_EXPORT(SCREEN) std FTXUI_EXPORT(SCREEN) std std::wstring to_wstring(T s)
size_t GlyphIterate(std::string_view input, int glyph_offset, size_t start)
bool IsFullWidth(uint32_t ucs)
size_t GlyphNext(std::string_view input, size_t start)
constexpr std::array< Interval, 123 > g_full_width_characters
constexpr std::array< WordBreakPropertyInterval, 1100 > g_word_break_intervals