OXYGENHUB
◆ main openmsx / src / console / ConsoleLine.cc
2.1 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#include "ConsoleLine.hh"
2
3
#include "narrow.hh"
4
#include "stl.hh"
5
#include "strCat.hh"
6
#include "utf8_unchecked.hh"
7
8
#include <algorithm>
9
#include <ranges>
10
11
namespace openmsx {
12
13
ConsoleLine::ConsoleLine(std::string line_, imColor color)
14
	: line(std::move(line_))
15
	, chunks(1, {color, 0})
16
{
17
}
18
19
void ConsoleLine::addChunk(std::string_view text, imColor color)
20
{
21
	chunks.push_back({.color = color, .pos = line.size()});
22
	line.append(text.data(), text.size());
23
}
24
25
void ConsoleLine::addLine(const ConsoleLine& ln)
26
{
27
	auto oldN = chunks.size();
28
	auto oldPos = line.size();
29
30
	strAppend(line, ln.line);
31
32
	append(chunks, ln.chunks);
33
	for (auto it = chunks.begin() + oldN, et = chunks.end(); it != et; ++it) {
34
		it->pos += oldPos;
35
	}
36
}
37
38
/** Split this line at a given column number.
39
	* This line will contain (up to) 'column' number of characters.
40
	* The remainder of the line is returned, this could be an empty line. */
41
ConsoleLine ConsoleLine::splitAtColumn(unsigned column)
42
{
43
	ConsoleLine result;
44
	if (line.empty()) return result;
45
	assert(!chunks.empty());
46
47
	auto it = line.begin(), et = line.end();
48
	while ((it != et) && column--) {
49
		utf8::unchecked::next(it);
50
	}
51
	auto pos = narrow<unsigned>(std::distance(line.begin(), it));
52
53
	auto it2 = std::ranges::upper_bound(chunks, pos, {}, &Chunk::pos);
54
	assert(it2 != chunks.begin());
55
	auto splitColor = it2[-1].color;
56
57
	if (it != et) {
58
		result.addChunk(std::string_view{it, et}, splitColor);
59
		result.chunks.insert(result.chunks.end(), it2, chunks.end());
60
		for (auto& c : std::views::drop(result.chunks, 1)) {
61
			c.pos -= pos;
62
		}
63
	}
64
65
	line.erase(it, et);
66
	if (it2[-1].pos == pos) --it2;
67
	chunks.erase(it2, chunks.end());
68
69
	return result;
70
}
71
72
size_t ConsoleLine::numChars() const
73
{
74
	return utf8::unchecked::size(line);
75
}
76
77
imColor ConsoleLine::chunkColor(size_t i) const
78
{
79
	assert(i < chunks.size());
80
	return chunks[i].color;
81
}
82
83
std::string_view ConsoleLine::chunkText(size_t i) const
84
{
85
	assert(i < chunks.size());
86
	auto pos = chunks[i].pos;
87
	auto len = ((i + 1) == chunks.size())
88
	         ? std::string_view::npos
89
	         : chunks[i + 1].pos - pos;
90
	return std::string_view(line).substr(pos, len);
91
}
92
93
} // namespace openmsx