1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
#ifndef TEACHOS_X86_64_VGA_TEXT_BUFFER_HPP
#define TEACHOS_X86_64_VGA_TEXT_BUFFER_HPP
// IWYU pragma: private, include <arch/vga/text.hpp>
#include <arch/vga/text/attribute.hpp>
#include <cstddef>
#include <span>
#include <string_view>
#include <utility>
namespace arch::vga::text
{
//! A VGA text buffer.
//!
//! VGA text mode presents a linear buffer of so-called cells. Each cell consists of a single code point and a
//! rendering attribute. The codepoint determines the character being rendered in a specific cell, while the attribute
//! determines the visual style of that cell.
//!
//! @see text::attribute
struct buffer
{
using cell = std::pair<char, std::byte>;
//! Create a new buffer.
//!
//! @param width The width of the buffer
//! @param height The height of the buffer
//! @param start A pointer to the first byte of the buffer.
//! @param position The starting position for the first write to the buffer
buffer(std::size_t width, std::size_t height, cell * start, std::size_t position = 0);
//! Clear the buffer.
//!
//! Clearing the buffer ensures it is filled with zeroes, effectively erasing all data and resetting the output
//! position to the start of the buffer.
auto clear() -> void;
//! Write a string of formatted code points to the buffer.
//!
//! @param code_points A string of (8-bit) code points to write to the buffer.
//! @param attribute The formatting to apply to the written sequence of code points.
auto write(std::string_view code_points, attribute attribute) -> void;
//! Write a single, formatted code point to the buffer.
//!
//! @param code_point A single (8-bit) code point
//! @param attribute The formatting to apply to the code point.
auto write(char code_point, attribute attribute) -> void;
//! Move the output position to a new line and scroll the buffer if necessary.
auto newline() -> void;
//! Scroll the buffer contents.
//!
//! @param nof_lines The number of lines to scroll up.
auto scroll(std::size_t nof_lines = 1) -> void;
private:
//! Get column number of the current cell.
[[nodiscard]] auto column() const noexcept -> std::ptrdiff_t;
//! Get the line number of the current cell.
[[nodiscard]] auto line() const noexcept -> std::ptrdiff_t;
//! Process the semantics of special code points, for example newlines and carriage returns.
//!
//! @param code_point The code point to process.
//! @param attribute The attribute to use when writing to the text buffer.
//! @return @p true iff. the code point was handled, @p false otherwise.
auto handle_special_code_point(char code_point, attribute attribute) -> bool;
//! Perform the actual output to the buffer.
//!
//! @param code_points The code points to output..
//! @param attribute The attribute to use when writing to the text buffer.
auto do_write(std::string_view code_points, attribute attribute) -> void;
//! Perform the actual output to the buffer.
//!
//! @param code_point The code point to output.
//! @param attribute The attribute to use when writing to the text buffer.
auto do_write(char code_point, attribute attribute) -> void;
//! The width, in cells, of the buffer.
std::size_t m_width{};
//! The height, in cells, of the buffer.
std::size_t m_height{};
//! The text mode data buffer.
std::span<cell> m_buffer;
//! The position of the next cell to be written to.
std::size_t m_position{};
};
} // namespace arch::vga::text
#endif
|