diff --git a/src/sago/SagoTextBox.cpp b/src/sago/SagoTextBox.cpp index 9a0d058..26ad966 100644 --- a/src/sago/SagoTextBox.cpp +++ b/src/sago/SagoTextBox.cpp @@ -25,6 +25,7 @@ SOFTWARE. #include "SagoTextBox.hpp" #include "SagoTextField.hpp" #include +#include namespace sago { @@ -74,6 +75,10 @@ void SagoTextBox::SetOutline(int outlineSize, const SDL_Color& color) { data->outlineColor = color; } +void SagoTextBox::SetMaxWidth(int width) { + data->maxWidth = width; +} + const std::string& SagoTextBox::GetText() const { return data->text; } @@ -89,18 +94,61 @@ void SagoTextBox::AppendLineToCache(const std::string& text) { tf.SetText(text.c_str()); } +void SagoTextBox::SplitAndAppendLineToCache(TTF_Font* font, const std::string& text) { + int width = data->maxWidth; + TTF_SizeUTF8(font, text.c_str(),&width, nullptr); + std::cerr << "Width: " << width << "\n"; + if (data->maxWidth <= 0 || width <= data->maxWidth) { + AppendLineToCache(text); + return; + } + int splitLocation = 1; + bool splitDone = false; + while (!splitDone) { + size_t nextSpace = text.find(' ', splitLocation+1); + std::string attemptSubString = text.substr(0, nextSpace); + TTF_SizeUTF8(font, attemptSubString.c_str(),&width, nullptr); + if (width <= data->maxWidth && nextSpace != std::string::npos) { + splitLocation = nextSpace; + } + else { + splitDone = true; + } + } + if (splitLocation == 1) { + splitDone = false; + while (!splitDone) { + size_t nextSplit = splitLocation+1; + std::string attemptSubString = text.substr(0, nextSplit); + TTF_SizeUTF8(font, attemptSubString.c_str(),&width, nullptr); + if (width <= data->maxWidth && nextSplit != text.length()) { + splitLocation = nextSplit; + } + else { + splitDone = true; + } + } + } + std::string firstPart = text.substr(0, splitLocation); + AppendLineToCache(firstPart); + std::string secondPart = text.substr(splitLocation+1); + SplitAndAppendLineToCache(font, secondPart); +} + void SagoTextBox::UpdateCache() { + TTF_Font *font = data->tex->getFontPtr(data->fontName, data->fontSize); const char delim = '\n'; const std::string& s = data->text; auto start = 0U; auto end = s.find(delim); while (end != std::string::npos) { - AppendLineToCache(s.substr(start, end - start)); + const std::string& theSubString = s.substr(start, end - start); + SplitAndAppendLineToCache(font, theSubString); start = end + 1; end = s.find(delim, start); } - AppendLineToCache(s.substr(start, end)); + SplitAndAppendLineToCache(font, s.substr(start, end)); data->renderedText = data->text; } diff --git a/src/sago/SagoTextBox.hpp b/src/sago/SagoTextBox.hpp index ba7b850..2658371 100644 --- a/src/sago/SagoTextBox.hpp +++ b/src/sago/SagoTextBox.hpp @@ -40,11 +40,13 @@ public: void SetFont(const char* fontName); void SetFontSize(int fontSize); void SetOutline(int outlineSize, const SDL_Color& color); + void SetMaxWidth(int width); const std::string& GetText() const; void Draw(SDL_Renderer* target, int x, int y); void UpdateCache(); private: void AppendLineToCache(const std::string& text); + void SplitAndAppendLineToCache(TTF_Font* font, const std::string& text); SagoTextBox(const SagoTextBox& orig) = delete; SagoTextBox& operator=(const SagoTextBox& base) = delete; struct SagoTextBoxData; diff --git a/src/saland.cpp b/src/saland.cpp index b383e8b..d51b829 100644 --- a/src/saland.cpp +++ b/src/saland.cpp @@ -77,8 +77,10 @@ public: textField.SetText("Saland Adventures - The game that has a very long subtitle to test the outline"); textField.SetOutline(3, SDL_Color{255,165,0,255}); textField.Draw(target, 10, 10); - textBox.SetText("This is some text. It is also quite long. \nIt must take several lines!\nEven 3 lines!\nand 4!\nAlso5\n\nAnd a blank one above!gg\ngg"); + textBox.SetText("This is some text. It is also quite long. \nIt must take several lines!\nEven 3 lines!\nand 4!\nAlso5\n\nAnd a blank one above!gg\ngg" + "\nabcdefghijklmnopqrstuvwxyz"); textBox.SetOutline(1, SDL_Color{255,0,0,255}); + textBox.SetMaxWidth(300); textBox.Draw(target, 300,300); circleRGBA(target, 150, 150, 75,