6#include "fifechan/text.hpp"
16#include <utf8cpp/utf8.h>
19#include "fifechan/exception.hpp"
20#include "fifechan/font.hpp"
21#include "fifechan/rectangle.hpp"
31 Text::Text(std::string
const & content)
33 std::string::size_type lastPos = 0;
34 std::string::size_type pos = content.find(
'\n', lastPos);
36 for (; pos != std::string::npos; pos = content.find(
'\n', lastPos)) {
37 int const length = pos - lastPos;
38 std::string
const sub = content.substr(lastPos, length);
44 std::string
const sub = content.substr(lastPos);
65 std::string::size_type lastPos = 0;
66 std::string::size_type pos = 0;
68 for (; (pos = content.find(
'\n', lastPos)) != std::string::npos; lastPos = pos + 1) {
69 int const length = pos - lastPos;
70 std::string
const sub = content.substr(lastPos, length);
75 std::string
const sub = content.substr(lastPos);
93 for (
size_t i = 0; i <
mRows.size() - 1; ++i) {
94 result.append(
mRows.at(i)).append(
"\n");
97 result.append(
mRows.back());
104 if (row >=
mRows.size()) {
107 assert(
"content is valid utf8" && utf8::is_valid(content.begin(), content.end()));
109 mRows.at(row) = content;
114 for (
char const i : row) {
119 assert(
"row is valid utf8" && utf8::is_valid(row.begin(), row.end()));
121 mRows.push_back(row);
126 unsigned int const totalRows =
mRows.size();
128 if (position >= totalRows) {
129 if (position == totalRows) {
136 for (
char const i : row) {
138 throwException(
"Line feed not allowed in the row to be inserted!");
141 assert(
"row is valid utf8" && utf8::is_valid(row.begin(), row.end()));
148 if (row >=
mRows.size()) {
157 if (row >=
mRows.size()) {
161 return mRows.at(row);
166 assert(
"character is valid unicode" && character >= 0 && character <= 0x10FFFF);
169 char const c =
static_cast<char>(character);
173 mRows.emplace_back(
"");
175 mRows.emplace_back(1, c);
179 std::string
const tail =
196 if (
mRows.empty() || numberOfCharacters == 0) {
201 if (numberOfCharacters < 0) {
202 while (numberOfCharacters != 0) {
222 numberOfCharacters++;
224 }
else if (numberOfCharacters > 0) {
226 while (numberOfCharacters != 0) {
243 numberOfCharacters--;
257 if (
mRows.empty() || position < 0) {
264 unsigned int const pos =
static_cast<unsigned int>(position);
265 unsigned int total = 0;
267 for (
unsigned int i = 0; i <
mRows.size(); ++i) {
268 unsigned int const rowLen =
static_cast<unsigned int>(
mRows.at(i).size());
270 if (pos < total + rowLen) {
277 if (pos == total + rowLen) {
279 if (i + 1 <
mRows.size()) {
299 if (contentChars == 0) {
313 assert(
"font is not null" && font !=
nullptr);
314 assert(
"font height is positive" && font->getHeight() > 0);
336 if (
mRows.empty() || column < 0) {
338 }
else if (std::cmp_greater(column,
mRows.at(
mCaretRow).size())) {
349 if (
mRows.empty() || row < 0) {
351 }
else if (std::cmp_greater_equal(row,
mRows.size())) {
362 assert(
"font is not null" && font !=
nullptr);
373 assert(
"font is not null" && font !=
nullptr);
374 assert(
"font height is positive" && font->getHeight() > 0);
381 assert(
"font is not null" && font !=
nullptr);
382 assert(
"font height is positive" && font->getHeight() > 0);
385 return {0, 0, font->getWidth(
" "), font->getHeight()};
389 for (
auto const & mRow :
mRows) {
390 int const w = font->getWidth(mRow);
391 width = std::max(width, w);
394 auto h =
static_cast<int>(font->getHeight() *
mRows.size());
395 auto w = width + font->getWidth(
" ");
402 assert(
"font is not null" && font !=
nullptr);
403 assert(
"font height is positive" && font->getHeight() > 0);
408 dim.
width = font->getWidth(
" ");
409 dim.
height = font->getHeight() + 2;
430 return std::accumulate(
mRows.begin(),
mRows.end(),
size_t{0}, [](
size_t sum,
auto const & row) {
431 return sum + row.size() + 1;
442 if (row >=
mRows.size()) {
446 return mRows.at(row).size();
451 unsigned int total = 0;
452 for (
auto i = 0; std::cmp_less(i,
mCaretRow); i++) {
454 total +=
mRows.at(i).size() + 1;
Abstract interface for font rendering.
Represents a rectangular area (X, Y, Width, Height).
int width
Holds the width of the rectangle.
int y
Holds the x coordinate of the rectangle.
int x
Holds the x coordinate of the rectangle.
int height
Holds the height of the rectangle.
unsigned int mCaretColumn
Holds the column the caret is in.
virtual void setCaretColumn(int column)
Sets the column the caret should be in.
virtual unsigned int getNumberOfCharacters() const
Gets the number of characters in the text.
virtual unsigned int getMaximumCaretRow() const
Gets the maximum row the caret can be in.
virtual void setContent(std::string const &content)
Sets the content of the text.
virtual unsigned int getNumberOfRows() const
Gets the number of rows in the text.
virtual int getWidth(int row, Font *font) const
Gets the width in pixels of a row.
virtual std::string & getRow(unsigned int row)
Gets a reference to a row.
virtual void setCaretRow(int row)
Sets the row the caret should be in.
virtual int getCaretPosition() const
Gets the caret position.
virtual ~Text()
Virtual destructor.
virtual void addRow(std::string const &row)
Adds a row to the content.
virtual void setRow(unsigned int row, std::string const &content)
Sets the content of a row.
virtual void remove(int numberOfCharacters)
Removes a given number of characters at starting at the current caret position.
unsigned int mCaretRow
Holds the row the caret is in.
virtual int getCaretColumn() const
Gets the column the caret is currently in.
virtual void insertRow(std::string const &row, unsigned int position)
Inserts a row before the specified row position.
virtual void setCaretPosition(int position)
Sets the caret position.
virtual int getCaretX(Font *font) const
Gets the x coordinate of the caret in pixels given a font.
unsigned int mCaretPosition
Holds the position of the caret.
virtual int getCaretRow() const
Gets the row the caret is currently in.
virtual void eraseRow(unsigned int row)
Erases the given row.
virtual int getCaretY(Font *font) const
Gets the y coordinate of the caret in pixels given a font.
std::vector< std::string > mRows
Holds the text row by row.
virtual std::string getContent() const
Gets the content of the text.
virtual void insert(int character)
Inserts a character at the current caret position.
void calculateCaretPositionFromRowAndColumn()
Calculates the caret position from the caret row and caret column.
virtual Rectangle getDimension(Font *font) const
Gets the dimension in pixels of the text given a font.
virtual Rectangle getCaretDimension(Font *font) const
Gets the caret dimension relative to this text.
Used replacement tokens by configure_file():
void throwException(std::string const &message, std::source_location location=std::source_location::current())
Throw an Exception capturing the current source location.