git repos / blockattack-game

blame: source/code/sago/SagoTextField.cpp

normal view · raw

55ea55dd sago007 2018-03-24 16:07 1
/*
55ea55dd sago007 2018-03-24 16:07 2
Copyright (c) 2018 Poul Sander
55ea55dd sago007 2018-03-24 16:07 3
55ea55dd sago007 2018-03-24 16:07 4
Permission is hereby granted, free of charge, to any person
55ea55dd sago007 2018-03-24 16:07 5
obtaining a copy of this software and associated documentation files
55ea55dd sago007 2018-03-24 16:07 6
(the "Software"), to deal in the Software without restriction,
55ea55dd sago007 2018-03-24 16:07 7
including without limitation the rights to use, copy, modify, merge,
55ea55dd sago007 2018-03-24 16:07 8
publish, distribute, sublicense, and/or sell copies of the Software,
55ea55dd sago007 2018-03-24 16:07 9
and to permit persons to whom the Software is furnished to do so,
55ea55dd sago007 2018-03-24 16:07 10
subject to the following conditions:
55ea55dd sago007 2018-03-24 16:07 11
55ea55dd sago007 2018-03-24 16:07 12
The above copyright notice and this permission notice shall be
55ea55dd sago007 2018-03-24 16:07 13
included in all copies or substantial portions of the Software.
55ea55dd sago007 2018-03-24 16:07 14
55ea55dd sago007 2018-03-24 16:07 15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
55ea55dd sago007 2018-03-24 16:07 16
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
55ea55dd sago007 2018-03-24 16:07 17
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
55ea55dd sago007 2018-03-24 16:07 18
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
55ea55dd sago007 2018-03-24 16:07 19
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
55ea55dd sago007 2018-03-24 16:07 20
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
55ea55dd sago007 2018-03-24 16:07 21
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
55ea55dd sago007 2018-03-24 16:07 22
SOFTWARE.
55ea55dd sago007 2018-03-24 16:07 23
*/
55ea55dd sago007 2018-03-24 16:07 24
55ea55dd sago007 2018-03-24 16:07 25
#include "SagoTextField.hpp"
55ea55dd sago007 2018-03-24 16:07 26
#include <iostream>
55ea55dd sago007 2018-03-24 16:07 27
#include <SDL_ttf.h>
55ea55dd sago007 2018-03-24 16:07 28
55ea55dd sago007 2018-03-24 16:07 29
namespace sago {
55ea55dd sago007 2018-03-24 16:07 30
55ea55dd sago007 2018-03-24 16:07 31
	class OutlineHandler {
55ea55dd sago007 2018-03-24 16:07 32
		TTF_Font* font;
55ea55dd sago007 2018-03-24 16:07 33
		int originalOutline = 0;
55ea55dd sago007 2018-03-24 16:07 34
		int targetOutline;
55ea55dd sago007 2018-03-24 16:07 35
		bool doChange = false;
55ea55dd sago007 2018-03-24 16:07 36
	public:
55ea55dd sago007 2018-03-24 16:07 37
		OutlineHandler(TTF_Font* font, int outline) : font{font}, targetOutline{outline} {
55ea55dd sago007 2018-03-24 16:07 38
			originalOutline = TTF_GetFontOutline(font);
55ea55dd sago007 2018-03-24 16:07 39
			if (originalOutline == targetOutline) {
55ea55dd sago007 2018-03-24 16:07 40
				return;
55ea55dd sago007 2018-03-24 16:07 41
			}
55ea55dd sago007 2018-03-24 16:07 42
			doChange = true;
55ea55dd sago007 2018-03-24 16:07 43
			TTF_SetFontOutline(font, targetOutline);
55ea55dd sago007 2018-03-24 16:07 44
		};
55ea55dd sago007 2018-03-24 16:07 45
		
55ea55dd sago007 2018-03-24 16:07 46
		void reset() {
55ea55dd sago007 2018-03-24 16:07 47
			if (doChange) {
55ea55dd sago007 2018-03-24 16:07 48
				TTF_SetFontOutline(font,originalOutline);
55ea55dd sago007 2018-03-24 16:07 49
				doChange = false;
55ea55dd sago007 2018-03-24 16:07 50
			}
55ea55dd sago007 2018-03-24 16:07 51
		}
55ea55dd sago007 2018-03-24 16:07 52
		
55ea55dd sago007 2018-03-24 16:07 53
		~OutlineHandler() {
55ea55dd sago007 2018-03-24 16:07 54
			reset();
55ea55dd sago007 2018-03-24 16:07 55
		}
55ea55dd sago007 2018-03-24 16:07 56
	private:
55ea55dd sago007 2018-03-24 16:07 57
		OutlineHandler(const OutlineHandler& orig) = delete;
55ea55dd sago007 2018-03-24 16:07 58
		OutlineHandler& operator=(const OutlineHandler& base) = delete;
55ea55dd sago007 2018-03-24 16:07 59
	};
55ea55dd sago007 2018-03-24 16:07 60
	
55ea55dd sago007 2018-03-24 16:07 61
struct SagoTextField::SagoTextFieldData {
1a09fcd5 sago007 2018-03-25 13:32 62
	const sago::SagoDataHolder* tex = nullptr;
55ea55dd sago007 2018-03-24 16:07 63
	SDL_Surface* textSurface = nullptr;
55ea55dd sago007 2018-03-24 16:07 64
	SDL_Texture* texture = nullptr;
55ea55dd sago007 2018-03-24 16:07 65
	SDL_Surface* outlineTextSurface = nullptr;
55ea55dd sago007 2018-03-24 16:07 66
	SDL_Texture* outlineTexture = nullptr;
55ea55dd sago007 2018-03-24 16:07 67
	std::string fontName = "freeserif";
55ea55dd sago007 2018-03-24 16:07 68
	SDL_Color color = { 255, 255, 255, 0 };
55ea55dd sago007 2018-03-24 16:07 69
	SDL_Color outlineColor = { 255, 255, 0, 0 };
55ea55dd sago007 2018-03-24 16:07 70
	int fontSize = 16;
55ea55dd sago007 2018-03-24 16:07 71
	int outline = 0;
55ea55dd sago007 2018-03-24 16:07 72
	std::string text = "";
55ea55dd sago007 2018-03-24 16:07 73
	std::string renderedText = "";
55ea55dd sago007 2018-03-24 16:07 74
	Uint64 renderedVersion = 0;
55ea55dd sago007 2018-03-24 16:07 75
};
55ea55dd sago007 2018-03-24 16:07 76
	
55ea55dd sago007 2018-03-24 16:07 77
SagoTextField::SagoTextField() {
55ea55dd sago007 2018-03-24 16:07 78
	data = new SagoTextFieldData();
55ea55dd sago007 2018-03-24 16:07 79
}
55ea55dd sago007 2018-03-24 16:07 80
55ea55dd sago007 2018-03-24 16:07 81
SagoTextField::SagoTextField(SagoTextField&& o) noexcept {
55ea55dd sago007 2018-03-24 16:07 82
	data = o.data;
55ea55dd sago007 2018-03-24 16:07 83
	o.data = nullptr;
55ea55dd sago007 2018-03-24 16:07 84
}
55ea55dd sago007 2018-03-24 16:07 85
55ea55dd sago007 2018-03-24 16:07 86
SagoTextField::~SagoTextField() {
55ea55dd sago007 2018-03-24 16:07 87
	if(!data) {
55ea55dd sago007 2018-03-24 16:07 88
		return;
55ea55dd sago007 2018-03-24 16:07 89
	}
55ea55dd sago007 2018-03-24 16:07 90
	ClearCache();
55ea55dd sago007 2018-03-24 16:07 91
	delete data;
55ea55dd sago007 2018-03-24 16:07 92
}
55ea55dd sago007 2018-03-24 16:07 93
1a09fcd5 sago007 2018-03-25 13:32 94
void SagoTextField::SetHolder(const SagoDataHolder* holder) {
55ea55dd sago007 2018-03-24 16:07 95
	data->tex = holder;
55ea55dd sago007 2018-03-24 16:07 96
}
55ea55dd sago007 2018-03-24 16:07 97
55ea55dd sago007 2018-03-24 16:07 98
void SagoTextField::SetText(const char* text) {
55ea55dd sago007 2018-03-24 16:07 99
	data->text = text;
55ea55dd sago007 2018-03-24 16:07 100
}
55ea55dd sago007 2018-03-24 16:07 101
55ea55dd sago007 2018-03-24 16:07 102
void SagoTextField::SetColor(const SDL_Color& color) {
55ea55dd sago007 2018-03-24 16:07 103
	data->color = color;
55ea55dd sago007 2018-03-24 16:07 104
}
55ea55dd sago007 2018-03-24 16:07 105
55ea55dd sago007 2018-03-24 16:07 106
void SagoTextField::SetFont(const char* fontName) {
55ea55dd sago007 2018-03-24 16:07 107
	data->fontName = fontName;
55ea55dd sago007 2018-03-24 16:07 108
}
55ea55dd sago007 2018-03-24 16:07 109
55ea55dd sago007 2018-03-24 16:07 110
void SagoTextField::SetFontSize(int fontSize) {
55ea55dd sago007 2018-03-24 16:07 111
	data->fontSize = fontSize;
55ea55dd sago007 2018-03-24 16:07 112
}
55ea55dd sago007 2018-03-24 16:07 113
55ea55dd sago007 2018-03-24 16:07 114
void SagoTextField::SetOutline(int outlineSize, const SDL_Color& color) {
55ea55dd sago007 2018-03-24 16:07 115
	data->outline = outlineSize;
55ea55dd sago007 2018-03-24 16:07 116
	data->outlineColor = color;
55ea55dd sago007 2018-03-24 16:07 117
}
55ea55dd sago007 2018-03-24 16:07 118
55ea55dd sago007 2018-03-24 16:07 119
const std::string& SagoTextField::GetText() const {
55ea55dd sago007 2018-03-24 16:07 120
	return data->text;
55ea55dd sago007 2018-03-24 16:07 121
}
55ea55dd sago007 2018-03-24 16:07 122
55ea55dd sago007 2018-03-24 16:07 123
void SagoTextField::ClearCache() {
55ea55dd sago007 2018-03-24 16:07 124
	if (!data->tex) {
55ea55dd sago007 2018-03-24 16:07 125
		std::cerr << "FATAL: DataHolder not set!\n";
55ea55dd sago007 2018-03-24 16:07 126
		abort();
55ea55dd sago007 2018-03-24 16:07 127
	}
55ea55dd sago007 2018-03-24 16:07 128
	if (data->texture) {
55ea55dd sago007 2018-03-24 16:07 129
		SDL_DestroyTexture(data->texture);
55ea55dd sago007 2018-03-24 16:07 130
		data->texture = nullptr;
55ea55dd sago007 2018-03-24 16:07 131
	}
55ea55dd sago007 2018-03-24 16:07 132
	if (data->textSurface) {
55ea55dd sago007 2018-03-24 16:07 133
		SDL_FreeSurface(data->textSurface);
55ea55dd sago007 2018-03-24 16:07 134
		data->textSurface = nullptr;
55ea55dd sago007 2018-03-24 16:07 135
	}
55ea55dd sago007 2018-03-24 16:07 136
	if (data->outlineTexture) {
55ea55dd sago007 2018-03-24 16:07 137
		SDL_DestroyTexture(data->outlineTexture);
55ea55dd sago007 2018-03-24 16:07 138
		data->outlineTexture = nullptr;
55ea55dd sago007 2018-03-24 16:07 139
	}
55ea55dd sago007 2018-03-24 16:07 140
	if (data->outlineTextSurface) {
55ea55dd sago007 2018-03-24 16:07 141
		SDL_FreeSurface(data->outlineTextSurface);
55ea55dd sago007 2018-03-24 16:07 142
		data->outlineTextSurface = nullptr;
55ea55dd sago007 2018-03-24 16:07 143
	}
55ea55dd sago007 2018-03-24 16:07 144
}
55ea55dd sago007 2018-03-24 16:07 145
55ea55dd sago007 2018-03-24 16:07 146
void SagoTextField::UpdateCache(SDL_Renderer* target) {
55ea55dd sago007 2018-03-24 16:07 147
	ClearCache();
55ea55dd sago007 2018-03-24 16:07 148
	TTF_Font *font = data->tex->getFontPtr(data->fontName, data->fontSize);
55ea55dd sago007 2018-03-24 16:07 149
	data->textSurface = TTF_RenderUTF8_Blended (font, data->text.c_str(), data->color);
55ea55dd sago007 2018-03-24 16:07 150
	data->texture = SDL_CreateTextureFromSurface(target, data->textSurface);
55ea55dd sago007 2018-03-24 16:07 151
	int textWidth = 0;
55ea55dd sago007 2018-03-24 16:07 152
	SDL_QueryTexture(data->texture, NULL, NULL, &textWidth, NULL);
55ea55dd sago007 2018-03-24 16:07 153
	if (data->outline > 0) {
55ea55dd sago007 2018-03-24 16:07 154
		OutlineHandler oh(font, data->outline);
55ea55dd sago007 2018-03-24 16:07 155
		data->outlineTextSurface = TTF_RenderUTF8_Blended (font, data->text.c_str(), data->outlineColor);
55ea55dd sago007 2018-03-24 16:07 156
		data->outlineTexture = SDL_CreateTextureFromSurface(target, data->outlineTextSurface);
55ea55dd sago007 2018-03-24 16:07 157
		oh.reset();
55ea55dd sago007 2018-03-24 16:07 158
	}
55ea55dd sago007 2018-03-24 16:07 159
	data->renderedText = data->text;
55ea55dd sago007 2018-03-24 16:07 160
	data->renderedVersion = data->tex->getVersion();
55ea55dd sago007 2018-03-24 16:07 161
}
55ea55dd sago007 2018-03-24 16:07 162
55ea55dd sago007 2018-03-24 16:07 163
void SagoTextField::Draw(SDL_Renderer* target, int x, int y) {
55ea55dd sago007 2018-03-24 16:07 164
	if (data->text.empty()) {
55ea55dd sago007 2018-03-24 16:07 165
		return;
55ea55dd sago007 2018-03-24 16:07 166
	}
55ea55dd sago007 2018-03-24 16:07 167
	if (data->text != data->renderedText || data->renderedVersion != data->tex->getVersion()) {
55ea55dd sago007 2018-03-24 16:07 168
		UpdateCache(target);
55ea55dd sago007 2018-03-24 16:07 169
	}
55ea55dd sago007 2018-03-24 16:07 170
	if (!data->texture) {
55ea55dd sago007 2018-03-24 16:07 171
		return;
55ea55dd sago007 2018-03-24 16:07 172
	}
55ea55dd sago007 2018-03-24 16:07 173
	int texW = 0;
55ea55dd sago007 2018-03-24 16:07 174
	int texH = 0;
55ea55dd sago007 2018-03-24 16:07 175
	SDL_QueryTexture(data->texture, NULL, NULL, &texW, &texH);
55ea55dd sago007 2018-03-24 16:07 176
	SDL_Rect dstrect = { x, y, texW, texH };
55ea55dd sago007 2018-03-24 16:07 177
	if (data->outlineTexture) {
55ea55dd sago007 2018-03-24 16:07 178
		int outlineTexW = 0;
55ea55dd sago007 2018-03-24 16:07 179
		int outlineTexH = 0;
55ea55dd sago007 2018-03-24 16:07 180
		SDL_QueryTexture(data->outlineTexture, NULL, NULL, &outlineTexW, &outlineTexH);
55ea55dd sago007 2018-03-24 16:07 181
		SDL_Rect dstrectOutline = { x-(data->outline), y-(data->outline), outlineTexW, outlineTexH };
55ea55dd sago007 2018-03-24 16:07 182
		SDL_RenderCopy(target, data->outlineTexture, NULL, &dstrectOutline);
55ea55dd sago007 2018-03-24 16:07 183
	}
55ea55dd sago007 2018-03-24 16:07 184
	SDL_RenderCopy(target, data->texture, NULL, &dstrect);
55ea55dd sago007 2018-03-24 16:07 185
}
55ea55dd sago007 2018-03-24 16:07 186
55ea55dd sago007 2018-03-24 16:07 187
}  //namespace sago