FifeGUI 0.3.0
A C++ GUI library designed for games.
utf8stringeditor.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later OR BSD-3-Clause
2// SPDX-FileCopyrightText: 2004 - 2008 Olof Naessén and Per Larsson
3// SPDX-FileCopyrightText: 2013 - 2026 Fifengine contributors
4
5// Corresponding header include
6#include <fifechan/utf8stringeditor.hpp>
7
8// Standard library includes
9#include <cassert>
10#include <string>
11#include <utility>
12
13// Third-party library includes
14#include <utf8cpp/utf8.h>
15
16namespace fcn
17{
18
19 int UTF8StringEditor::nextChar(std::string const & text, int byteOffset)
20 {
21 assert("byteOffset is non-negative" && byteOffset >= 0);
22 assert("byteOffset is within text" && std::cmp_less(byteOffset, text.size()));
23 assert("text is valid utf8" && utf8::is_valid(text.begin(), text.end()));
24
25 std::string::const_iterator c;
26 std::string::const_iterator e;
27
28 c = text.begin() + byteOffset;
29 e = text.end();
30
31 utf8::next(c, e);
32 return std::string(text.begin(), c).size();
33 }
34
35 int UTF8StringEditor::prevChar(std::string const & text, int byteOffset)
36 {
37 assert("byteOffset is positive" && byteOffset > 0);
38 assert("byteOffset is within text" && std::cmp_less_equal(byteOffset, text.size()));
39 assert("text is valid utf8" && utf8::is_valid(text.begin(), text.end()));
40
41 std::string::const_iterator c;
42 std::string::const_iterator b;
43
44 c = text.begin() + byteOffset;
45 b = text.begin();
46
47 utf8::prior(c, b);
48 return std::string(b, c).size();
49 }
50
51 int UTF8StringEditor::eraseChar(std::string& text, int byteOffset)
52 {
53 assert("byteOffset is within text" && byteOffset >= 0 && std::cmp_less(byteOffset, text.size()));
54 assert("text is valid utf8" && utf8::is_valid(text.begin(), text.end()));
55
56 std::string::iterator begin;
57 std::string::iterator cur;
58 begin = text.begin() + byteOffset;
59 cur = begin;
60 utf8::next(cur, text.end());
61
62 text = std::string(text.begin(), begin) + std::string(cur, text.end());
63
64 return byteOffset;
65 }
66
67 int UTF8StringEditor::insertChar(std::string& text, int byteOffset, int ch)
68 {
69 assert("byteOffset is non-negative" && byteOffset >= 0);
70 assert("byteOffset is within text" && std::cmp_less_equal(byteOffset, text.size()));
71 assert("character is valid unicode code point" && ch >= 0 && ch <= 0x10FFFF && (ch < 0xD800 || ch > 0xDFFF));
72
73 std::string newText;
74 std::string::iterator cut;
75 int newOffset = 0;
76
77 newText = text.substr(0, byteOffset) + " ";
78 utf8::append(ch, newText.begin() + byteOffset);
79 cut = newText.begin() + byteOffset;
80 utf8::next(cut, newText.end());
81 newText.erase(cut, newText.end());
82 newOffset = newText.size();
83 text = newText + text.substr(byteOffset);
84
85 assert("result is valid utf8" && utf8::is_valid(text.begin(), text.end()));
86
87 return newOffset;
88 }
89
90 int UTF8StringEditor::countChars(std::string const & text, int byteOffset)
91 {
92 assert("byteOffset is non-negative" && byteOffset >= 0);
93 assert("byteOffset is within text bounds" && std::cmp_less_equal(byteOffset, text.size()));
94 assert("text is valid utf8" && utf8::is_valid(text.begin(), text.end()));
95
96 return utf8::distance(text.begin(), text.begin() + byteOffset);
97 }
98
99 int UTF8StringEditor::getOffset(std::string const & text, int charIndex)
100 {
101 assert("charIndex is non-negative" && charIndex >= 0);
102 assert("text is valid utf8" && utf8::is_valid(text.begin(), text.end()));
103
104 std::string::const_iterator cur;
105 std::string::const_iterator end;
106 int i = 0;
107
108 if (charIndex < 0) {
109 return 0;
110 }
111
112 cur = text.begin();
113 end = text.end();
114
115 for (i = 0; i < charIndex && cur != end; i++) {
116 utf8::next(cur, end);
117 }
118
119 return std::string(text.begin(), cur).size();
120 }
121}; // namespace fcn
static int insertChar(std::string &text, int byteOffset, int ch)
Insert a character at specified byte offset.
static int countChars(std::string const &text, int byteOffset)
Counts characters up to byteOffset.
static int eraseChar(std::string &text, int byteOffset)
Erase character at specified byte offset.
static int getOffset(std::string const &text, int charIndex)
Gets byte offset for character index.
static int nextChar(std::string const &text, int byteOffset)
Returns byte offset of the next character.
static int prevChar(std::string const &text, int byteOffset)
Returns byte offset of the previous character.
Used replacement tokens by configure_file():