/* * ===================================================================================== * * OpenMiner * * Copyright (C) 2018-2020 Unarelith, Quentin Bazin * Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md) * * This file is part of OpenMiner. * * OpenMiner 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. * * OpenMiner 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. * * You should have received a copy of the GNU Lesser General Public License * along with OpenMiner; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * ===================================================================================== */ #include #include "Color.hpp" #include "Font.hpp" #include "Text.hpp" Text::Text() : m_font(gk::ResourceHandler::getInstance().get("font-ascii")) { m_background.setFillColor(gk::Color::Transparent); } void Text::setString(const std::string &string) { if (m_string != string) { m_string = string; m_isUpdateNeeded = true; } } void Text::setColor(const gk::Color &color) { if (m_color != color) { m_color = color; m_isUpdateNeeded = true; } } void Text::setPadding(int x, int y) { if (m_padding.x != x || m_padding.y != y) { m_padding.x = x; m_padding.y = y; m_isUpdateNeeded = true; } } void Text::setMaxLineLength(unsigned int maxLineLength) { if (m_maxLineLength != maxLineLength) { m_maxLineLength = maxLineLength; m_isUpdateNeeded = true; } } void Text::draw(gk::RenderTarget &target, gk::RenderStates states) const { if (m_isUpdateNeeded) { updateVertexBuffer(); m_isUpdateNeeded = false; } if (m_verticesCount == 0) return; states.transform *= getTransform(); target.draw(m_background, states); states.transform.translate(m_padding.x, m_padding.y); states.texture = &m_font.texture(); states.vertexAttributes = VertexAttribute::Basic; glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); target.draw(m_vbo, GL_TRIANGLES, 0, m_verticesCount, states); } void Text::updateVertexBuffer() const { if (!m_isUpdateNeeded) return; std::vector vertices; u32 x = 0; u32 y = 0; u32 maxX = 0; gk::Color color = gk::Color{70, 70, 70, 255}; for(char c : m_string) { if (c == '\n' || (m_maxLineLength && x + m_font.getCharWidth(c) >= m_maxLineLength)) { y += m_font.getTileSize().y + 1; x = 0; continue; } addCharacter(x + 1, y + 1, color, c, vertices); x += m_font.getCharWidth(c); } x = 0; y = 0; color = m_color; for(char c : m_string) { if (c == '\n' || (m_maxLineLength && x + m_font.getCharWidth(c) >= m_maxLineLength)) { maxX = std::max(x, maxX); y += m_font.getTileSize().y + 1; x = 0; continue; } if (c == '[') color = Color::Blue; addCharacter(x, y, color, c, vertices); if (c == ']') color = m_color; x += m_font.getCharWidth(c); } m_verticesCount = vertices.size(); gk::VertexBuffer::bind(&m_vbo); m_vbo.setData(sizeof(Vertex) * m_verticesCount, vertices.data(), GL_DYNAMIC_DRAW); gk::VertexBuffer::bind(nullptr); m_size.x = std::max(x, maxX); m_size.y = y + m_font.getTileSize().y + 1; u32 backgroundX = std::max(m_background.getSize().x, m_size.x + m_padding.x); u32 backgroundY = std::max(m_background.getSize().y, m_size.y + m_padding.y); m_background.setSize(backgroundX, backgroundY); } void Text::addCharacter(u32 x, u32 y, const gk::Color &color, u8 c, std::vector &vertices) const { static const u8 coords[6][2] = { {1, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 1}, }; for (int i = 0 ; i < 6 ; ++i) { vertices.emplace_back(); Vertex &vertex = vertices.back(); vertex.coord3d[0] = x + coords[i][0] * m_font.getTileSize().x; vertex.coord3d[1] = y + coords[i][1] * m_font.getTileSize().y; vertex.coord3d[2] = 0; vertex.coord3d[3] = -1; vertex.color[0] = color.r; vertex.color[1] = color.g; vertex.color[2] = color.b; vertex.color[3] = color.a; gk::Vector2f texCoords = m_font.getTexCoords(c, coords[i][0], coords[i][1]); vertex.texCoord[0] = texCoords.x; vertex.texCoord[1] = texCoords.y; } }