2018-06-24 03:17:06 +02:00
|
|
|
/*
|
|
|
|
* =====================================================================================
|
|
|
|
*
|
2020-02-08 18:34:26 +09:00
|
|
|
* OpenMiner
|
|
|
|
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
|
2018-06-24 03:17:06 +02:00
|
|
|
*
|
2020-02-08 18:34:26 +09:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2018-06-24 03:17:06 +02:00
|
|
|
*
|
2020-02-08 18:34:26 +09:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
2018-06-24 03:17:06 +02:00
|
|
|
*
|
2020-02-08 18:34:26 +09:00
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
2018-06-24 03:17:06 +02:00
|
|
|
*
|
|
|
|
* =====================================================================================
|
|
|
|
*/
|
2018-12-29 02:23:23 +01:00
|
|
|
#include <gk/gl/Texture.hpp>
|
|
|
|
#include <gk/resource/ResourceHandler.hpp>
|
|
|
|
|
2018-12-30 23:47:51 +01:00
|
|
|
#include "Color.hpp"
|
2018-06-24 03:17:06 +02:00
|
|
|
#include "Text.hpp"
|
|
|
|
|
2018-12-29 02:23:23 +01:00
|
|
|
Text::Text() : m_texture(gk::ResourceHandler::getInstance().get<gk::Texture>("texture-font")) {
|
2020-02-21 23:58:15 +09:00
|
|
|
m_background.setFillColor(gk::Color::Transparent);
|
|
|
|
|
2018-06-25 22:30:38 +02:00
|
|
|
updateCharWidth();
|
2018-06-24 03:17:06 +02:00
|
|
|
}
|
|
|
|
|
2019-12-30 21:46:06 +09:00
|
|
|
void Text::setText(const std::string &text) {
|
|
|
|
if (m_text != text) {
|
|
|
|
m_text = text;
|
|
|
|
updateTextSprites();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Text::setColor(const gk::Color &color) {
|
|
|
|
if (m_color != color) {
|
|
|
|
m_color = color;
|
|
|
|
updateTextSprites();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-29 02:23:23 +01:00
|
|
|
void Text::draw(gk::RenderTarget &target, gk::RenderStates states) const {
|
2018-12-25 01:45:10 +01:00
|
|
|
states.transform *= getTransform();
|
2018-06-24 03:17:06 +02:00
|
|
|
|
2020-02-21 23:58:15 +09:00
|
|
|
target.draw(m_background, states);
|
|
|
|
|
|
|
|
states.transform.translate(m_padding.x, m_padding.y);
|
|
|
|
|
2018-12-29 02:23:23 +01:00
|
|
|
for(const gk::Sprite &sprite : m_textSprites) {
|
2018-06-26 06:38:20 +02:00
|
|
|
target.draw(sprite, states);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: USE A VBO INSTEAD
|
|
|
|
void Text::updateTextSprites() {
|
|
|
|
m_textSprites.clear();
|
|
|
|
|
2020-02-22 01:00:42 +09:00
|
|
|
unsigned int x = 0;
|
|
|
|
unsigned int y = 0;
|
|
|
|
unsigned int maxX = 0;
|
2018-12-29 02:23:23 +01:00
|
|
|
gk::Color color = gk::Color{70, 70, 70, 255};
|
2018-06-26 05:38:19 +02:00
|
|
|
for(char c : m_text) {
|
2020-02-22 01:00:42 +09:00
|
|
|
if (c == '\n' || (m_maxLineLength && x + m_charWidth[(u8)c] >= m_maxLineLength)) {
|
2019-12-30 20:19:16 +09:00
|
|
|
y += 9;
|
|
|
|
x = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-12-29 02:23:23 +01:00
|
|
|
gk::Sprite sprite{"texture-font", 8, 8};
|
2018-06-26 05:38:19 +02:00
|
|
|
sprite.setCurrentFrame(c);
|
2019-12-30 20:19:16 +09:00
|
|
|
sprite.setPosition(x + 1, y + 1, 0);
|
2018-06-26 05:38:19 +02:00
|
|
|
sprite.setColor(color);
|
2018-06-26 06:38:20 +02:00
|
|
|
m_textSprites.emplace_back(std::move(sprite));
|
2018-06-26 05:38:19 +02:00
|
|
|
x += m_charWidth[(u8)c];
|
|
|
|
}
|
|
|
|
x = 0;
|
2019-12-30 20:19:16 +09:00
|
|
|
y = 0;
|
2018-06-30 04:17:08 +02:00
|
|
|
color = m_color;
|
2018-06-24 03:17:06 +02:00
|
|
|
for(char c : m_text) {
|
2020-02-22 01:00:42 +09:00
|
|
|
if (c == '\n' || (m_maxLineLength && x + m_charWidth[(u8)c] >= m_maxLineLength)) {
|
2019-12-30 20:19:16 +09:00
|
|
|
maxX = std::max(x, maxX);
|
|
|
|
y += 9;
|
|
|
|
x = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-12-29 02:23:23 +01:00
|
|
|
gk::Sprite sprite{"texture-font", 8, 8};
|
2018-06-24 03:17:06 +02:00
|
|
|
sprite.setCurrentFrame(c);
|
2019-12-30 20:19:16 +09:00
|
|
|
sprite.setPosition(x, y, 0);
|
2018-06-26 05:38:19 +02:00
|
|
|
if (c == '[')
|
2018-12-30 23:47:51 +01:00
|
|
|
color = Color::Blue;
|
2018-06-26 05:38:19 +02:00
|
|
|
sprite.setColor(color);
|
2018-06-26 06:38:20 +02:00
|
|
|
m_textSprites.emplace_back(std::move(sprite));
|
2018-06-25 22:30:38 +02:00
|
|
|
x += m_charWidth[(u8)c];
|
2018-06-24 03:17:06 +02:00
|
|
|
}
|
2018-06-28 10:54:17 +02:00
|
|
|
|
2019-12-30 20:19:16 +09:00
|
|
|
m_size.x = std::max(x, maxX);
|
2020-02-22 01:00:42 +09:00
|
|
|
m_size.y = y + 9;
|
|
|
|
|
|
|
|
unsigned int backgroundX = std::max<int>(m_background.getSize().x, m_size.x + m_padding.x);
|
|
|
|
unsigned int backgroundY = std::max<int>(m_background.getSize().y, m_size.y + m_padding.y);
|
|
|
|
|
|
|
|
m_background.setSize(backgroundX, backgroundY);
|
2018-06-24 03:17:06 +02:00
|
|
|
}
|
|
|
|
|
2018-06-25 22:30:38 +02:00
|
|
|
// FIXME: Since I use the font from Minecraft assets, I needed to use
|
|
|
|
// this piece of code to make it look good
|
|
|
|
// I'll remove it later anyway
|
|
|
|
void Text::updateCharWidth() {
|
2019-04-13 15:06:52 +02:00
|
|
|
const int width = m_texture.getSize().x;
|
|
|
|
const int height = m_texture.getSize().y;
|
2020-01-22 14:18:31 +09:00
|
|
|
unsigned int *data = new unsigned int[width * height];
|
2018-06-25 22:30:38 +02:00
|
|
|
|
2018-12-29 02:23:23 +01:00
|
|
|
gk::Texture::bind(&m_texture);
|
2020-01-22 14:18:31 +09:00
|
|
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data);
|
2018-12-29 02:23:23 +01:00
|
|
|
gk::Texture::bind(nullptr);
|
2018-06-25 22:30:38 +02:00
|
|
|
|
2018-06-28 10:54:17 +02:00
|
|
|
const int charMaxHeight = height / 16;
|
|
|
|
const int charMaxWidth = width / 16;
|
2018-06-25 22:30:38 +02:00
|
|
|
|
2018-06-28 10:54:17 +02:00
|
|
|
for (int i = 0 ; i < 256 ; ++i) {
|
2018-06-25 22:30:38 +02:00
|
|
|
if (i == ' ') {
|
|
|
|
m_charWidth[i] = 4;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
int charX = i % 16;
|
|
|
|
int charY = i / 16;
|
|
|
|
|
|
|
|
if (i == 32)
|
|
|
|
m_charWidth[i] = 4;
|
|
|
|
|
|
|
|
int l1;
|
|
|
|
for (l1 = charMaxWidth - 1 ; l1 >= 0 ; --l1) {
|
|
|
|
int i2 = charX * charMaxWidth + l1;
|
|
|
|
bool flag1 = true;
|
|
|
|
|
|
|
|
for (int j2 = 0 ; j2 < charMaxHeight && flag1 ; ++j2) {
|
|
|
|
int k2 = (charY * charMaxWidth + j2) * width;
|
|
|
|
|
2018-06-28 10:54:17 +02:00
|
|
|
if ((data[i2 + k2] & 255) != 0)
|
2018-06-25 22:30:38 +02:00
|
|
|
flag1 = false;
|
|
|
|
}
|
|
|
|
|
2018-06-28 10:54:17 +02:00
|
|
|
if (!flag1) break;
|
2018-06-25 22:30:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
++l1;
|
2018-07-02 02:53:00 +02:00
|
|
|
m_charWidth[i] = 0.5f + l1 * (8.0f / charMaxWidth) + 1;
|
2018-06-25 22:30:38 +02:00
|
|
|
}
|
2020-01-22 14:18:31 +09:00
|
|
|
|
|
|
|
delete[] data;
|
2018-06-25 22:30:38 +02:00
|
|
|
}
|
2018-06-26 06:38:20 +02:00
|
|
|
|