git repos / saland

commit cc77cbc6

sago007 · 2018-03-17 15:58
cc77cbc643516809cd91dd4f715e7b95ffd6b73e patch · browse files
parent 7fd231cf94427d18532b348092a2bb7274e280c9

Multi line support

Changed files

A src/sago/SagoTextBox.cpp
A src/sago/SagoTextBox.hpp
M src/sago/SagoTextField.cpp before
M src/sago/SagoTextField.hpp before
M src/saland.cpp before
diff --git a/src/sago/SagoTextBox.cpp b/src/sago/SagoTextBox.cpp new file mode 100644 index 0000000..7c621bf --- /dev/null +++ b/src/sago/SagoTextBox.cpp
@@ -0,0 +1,119 @@
+/*
+Copyright (c) 2018 Poul Sander
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "SagoTextBox.hpp"
+#include "SagoTextField.hpp"
+#include <vector>
+#include <SDL/SDL_ttf.h>
+
+namespace sago {
+
+struct SagoTextBox::SagoTextBoxData {
+ sago::SagoDataHolder* tex = nullptr;
+ std::string fontName = "freeserif";
+ SDL_Color color = { 255, 255, 255, 0 };
+ SDL_Color outlineColor = { 255, 255, 0, 0 };
+ int fontSize = 16;
+ int outline = 0;
+ std::string text = "";
+ std::string renderedText = "";
+ std::vector<SagoTextField> lines;
+ int maxWidth = 0;
+};
+
+SagoTextBox::SagoTextBox() {
+ data = new SagoTextBoxData();
+}
+
+SagoTextBox::~SagoTextBox() {
+ delete data;
+}
+
+void SagoTextBox::SetHolder(SagoDataHolder* holder) {
+ data->tex = holder;
+}
+
+void SagoTextBox::SetText(const char* text) {
+ data->text = text;
+}
+
+void SagoTextBox::SetColor(const SDL_Color& color) {
+ data->color = color;
+}
+
+void SagoTextBox::SetFont(const char* fontName) {
+ data->fontName = fontName;
+}
+
+void SagoTextBox::SetFontSize(int fontSize) {
+ data->fontSize = fontSize;
+}
+
+void SagoTextBox::SetOutline(int outlineSize, const SDL_Color& color) {
+ data->outline = outlineSize;
+ data->outlineColor = color;
+}
+
+const std::string& SagoTextBox::GetText() const {
+ return data->text;
+}
+
+void SagoTextBox::AppendLineToCache(const std::string& text) {
+ data->lines.resize(data->lines.size()+1);
+ SagoTextField& tf = data->lines.back();
+ tf.SetHolder(data->tex);
+ tf.SetFont(data->fontName.c_str());
+ tf.SetFontSize(data->fontSize);
+ tf.SetColor(data->color);
+ tf.SetOutline(data->outline, data->outlineColor);
+ tf.SetText(text.c_str());
+}
+
+void SagoTextBox::UpdateCache() {
+ 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));
+ start = end + 1;
+ end = s.find(delim, start);
+ }
+ AppendLineToCache(s.substr(start, end));
+ data->renderedText = data->text;
+}
+
+void SagoTextBox::Draw(SDL_Renderer* target, int x, int y) {
+ if (data->text != data->renderedText) {
+ UpdateCache();
+ }
+ TTF_Font *font = data->tex->getFontPtr(data->fontName, data->fontSize);
+ int lineSkip = TTF_FontLineSkip(font);
+ for (size_t i = 0; i < data->lines.size(); ++i) {
+ data->lines[i].Draw(target, x, y+i*lineSkip);
+ }
+}
+
+} //namespace sago
\ No newline at end of file
diff --git a/src/sago/SagoTextBox.hpp b/src/sago/SagoTextBox.hpp new file mode 100644 index 0000000..ba7b850 --- /dev/null +++ b/src/sago/SagoTextBox.hpp
@@ -0,0 +1,57 @@
+/*
+Copyright (c) 2018 Poul Sander
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#ifndef SAGOTEXTBOX_HPP
+#define SAGOTEXTBOX_HPP
+
+#include "SagoDataHolder.hpp"
+#include "SagoTextField.hpp"
+
+namespace sago {
+
+class SagoTextBox {
+public:
+ SagoTextBox();
+ virtual ~SagoTextBox();
+ void SetHolder(SagoDataHolder* holder);
+ void SetText(const char* text);
+ void SetColor(const SDL_Color& color);
+ void SetFont(const char* fontName);
+ void SetFontSize(int fontSize);
+ void SetOutline(int outlineSize, const SDL_Color& color);
+ const std::string& GetText() const;
+ void Draw(SDL_Renderer* target, int x, int y);
+ void UpdateCache();
+private:
+ void AppendLineToCache(const std::string& text);
+ SagoTextBox(const SagoTextBox& orig) = delete;
+ SagoTextBox& operator=(const SagoTextBox& base) = delete;
+ struct SagoTextBoxData;
+ SagoTextBoxData *data;
+};
+
+} //namespace sago
+
+#endif /* SAGOTEXTBOX_HPP */
+
diff --git a/src/sago/SagoTextField.cpp b/src/sago/SagoTextField.cpp index 5181277..ce6cc23 100644 --- a/src/sago/SagoTextField.cpp +++ b/src/sago/SagoTextField.cpp
@@ -77,7 +77,15 @@ SagoTextField::SagoTextField() {
data = new SagoTextFieldData();
}
+SagoTextField::SagoTextField(SagoTextField&& o) noexcept {
+ data = o.data;
+ o.data = nullptr;
+}
+
SagoTextField::~SagoTextField() {
+ if(!data) {
+ return;
+ }
ClearCache();
delete data;
}
@@ -107,7 +115,7 @@ void SagoTextField::SetOutline(int outlineSize, const SDL_Color& color) {
data->outlineColor = color;
}
-std::string SagoTextField::GetText() const {
+const std::string& SagoTextField::GetText() const {
return data->text;
}
@@ -137,11 +145,13 @@ void SagoTextField::ClearCache() {
void SagoTextField::UpdateCache(SDL_Renderer* target) {
ClearCache();
TTF_Font *font = data->tex->getFontPtr(data->fontName, data->fontSize);
- data->textSurface = TTF_RenderText_Blended (font, data->text.c_str(), data->color);
+ data->textSurface = TTF_RenderUTF8_Blended (font, data->text.c_str(), data->color);
data->texture = SDL_CreateTextureFromSurface(target, data->textSurface);
+ int textWidth = 0;
+ SDL_QueryTexture(data->texture, NULL, NULL, &textWidth, NULL);
if (data->outline > 0) {
OutlineHandler oh(font, data->outline);
- data->outlineTextSurface = TTF_RenderText_Blended (font, data->text.c_str(), data->outlineColor);
+ data->outlineTextSurface = TTF_RenderUTF8_Blended (font, data->text.c_str(), data->outlineColor);
data->outlineTexture = SDL_CreateTextureFromSurface(target, data->outlineTextSurface);
oh.reset();
}
@@ -166,8 +176,8 @@ void SagoTextField::Draw(SDL_Renderer* target, int x, int y) {
int outlineTexW = 0;
int outlineTexH = 0;
SDL_QueryTexture(data->outlineTexture, NULL, NULL, &outlineTexW, &outlineTexH);
- SDL_Rect dstrect = { x-(outlineTexW-texW)/2, y-(outlineTexH-texH)/2, outlineTexW, outlineTexH };
- SDL_RenderCopy(target, data->outlineTexture, NULL, &dstrect);
+ SDL_Rect dstrectOutline = { x-(data->outline), y-(data->outline), outlineTexW, outlineTexH };
+ SDL_RenderCopy(target, data->outlineTexture, NULL, &dstrectOutline);
}
SDL_RenderCopy(target, data->texture, NULL, &dstrect);
}
diff --git a/src/sago/SagoTextField.hpp b/src/sago/SagoTextField.hpp index c4db9ab..99aaf03 100644 --- a/src/sago/SagoTextField.hpp +++ b/src/sago/SagoTextField.hpp
@@ -32,6 +32,8 @@ namespace sago {
class SagoTextField {
public:
SagoTextField();
+ SagoTextField(SagoTextField&& o) noexcept;
+ SagoTextField& operator=(const SagoTextField&& base) = delete;
virtual ~SagoTextField();
void SetHolder(SagoDataHolder* holder);
void SetText(const char* text);
@@ -39,7 +41,7 @@ public:
void SetFont(const char* fontName);
void SetFontSize(int fontSize);
void SetOutline(int outlineSize, const SDL_Color& color);
- std::string GetText() const;
+ const std::string& GetText() const;
void Draw(SDL_Renderer* target, int x, int y);
void UpdateCache(SDL_Renderer* target);
void ClearCache();
diff --git a/src/saland.cpp b/src/saland.cpp index f87003b..b383e8b 100644 --- a/src/saland.cpp +++ b/src/saland.cpp
@@ -43,6 +43,7 @@ https://github.com/sago007/saland
#include "sago/SagoMisc.hpp"
#include "sago/platform_folders.h"
#include "sagotmx/tmx_struct.h"
+#include "sago/SagoTextBox.hpp"
#if defined(_WIN32)
#include <windows.h>
@@ -62,6 +63,8 @@ public:
TitleScreen() {
textField.SetHolder(globalData.dataHolder);
textField.SetFontSize(30);
+ textBox.SetHolder(globalData.dataHolder);
+ textBox.SetFontSize(16);
}
virtual bool IsActive() override {
@@ -71,9 +74,12 @@ public:
virtual void Draw(SDL_Renderer* target) override {
- textField.SetText("Saland Adventures - The game that has a very long subtitle - to test the outline");
+ 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.SetOutline(1, SDL_Color{255,0,0,255});
+ textBox.Draw(target, 300,300);
circleRGBA(target,
150, 150, 75,
0, 0, 255, 255);
@@ -102,6 +108,7 @@ public:
private:
bool isActive = true;
sago::SagoTextField textField;
+ sago::SagoTextBox textBox;
};
void RunGameState(sago::GameStateInterface& state ) {