5#include "fifechan/text.hpp"
12#include "fifechan/exception.hpp"
13#include "fifechan/font.hpp"
14#include "fifechan/rectangle.hpp"
18 Text::Text() =
default;
20 Text::Text(std::string
const & content)
22 std::string::size_type lastPos = 0;
23 std::string::size_type pos = content.find(
'\n', lastPos);
25 for (; pos != std::string::npos; pos = content.find(
'\n', lastPos)) {
26 int const length = pos - lastPos;
27 std::string
const sub = content.substr(lastPos, length);
33 std::string
const sub = content.substr(lastPos);
39 Text::~Text() =
default;
49 std::string::size_type lastPos = 0;
50 std::string::size_type pos = 0;
52 for (; (pos = content.find(
'\n', lastPos)) != std::string::npos; lastPos = pos + 1) {
53 int const length = pos - lastPos;
54 std::string
const sub = content.substr(lastPos, length);
59 std::string
const sub = content.substr(lastPos);
72 for (
size_t i = 0; i <
mRows.size() - 1; ++i) {
73 result.append(
mRows[i]).append(
"\n");
76 result.append(
mRows.back());
83 if (row >=
mRows.size()) {
84 throwException(
"Row out of bounds!");
93 for (i = 0; i < row.size(); i++) {
95 throwException(
"Line feed not allowed in the row to be added!");
104 unsigned int const totalRows =
mRows.size();
106 if (position >= totalRows) {
107 if (position == totalRows) {
111 throwException(
"Position out of bounds!");
115 for (i = 0; i < row.size(); i++) {
116 if (row[i] ==
'\n') {
117 throwException(
"Line feed not allowed in the row to be inserted!");
126 if (row >=
mRows.size()) {
127 throwException(
"Row to be erased out of bounds!");
135 if (row >=
mRows.size()) {
136 throwException(
"Row out of bounds!");
144 char const c =
static_cast<char>(character);
148 mRows.emplace_back(
"");
150 mRows.emplace_back(1, c);
168 if (
mRows.empty() || numberOfCharacters == 0) {
173 if (numberOfCharacters < 0) {
174 while (numberOfCharacters != 0) {
194 numberOfCharacters++;
196 }
else if (numberOfCharacters > 0) {
198 while (numberOfCharacters != 0) {
215 numberOfCharacters--;
227 if (
mRows.empty() || position < 0) {
237 unsigned int total = 0;
238 for (i = 0; i <
mRows.size(); i++) {
239 if (std::cmp_less_equal(position, total +
mRows[i].size())) {
247 total +=
mRows[i].size() + 1;
280 if (
mRows.empty() || column < 0) {
293 if (
mRows.empty() || row < 0) {
295 }
else if (std::cmp_greater_equal(row,
mRows.size())) {
326 for (
auto const & mRow :
mRows) {
328 width = std::max(width, w);
332 auto w = width + font->
getWidth(
" ");
365 return std::accumulate(
mRows.begin(),
mRows.end(), 0U, [](
unsigned int sum,
auto const & row) {
366 return sum + row.size() + 1;
377 if (row >=
mRows.size()) {
381 return mRows[row].size();
386 unsigned int total = 0;
387 for (
auto i = 0; std::cmp_less(i,
mCaretRow); i++) {
389 total +=
mRows[i].size() + 1;
Abstract interface for font rendering.
virtual int getWidth(std::string const &text) const =0
Gets the width of a string.
virtual int getHeight() const =0
Gets the height of the glyphs in the font.
virtual int getStringIndexAt(std::string const &text, int x) const
Gets a string index in a string providing an x coordinate.
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 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.