diff --git a/client/source/core/ClientApplication.cpp b/client/source/core/ClientApplication.cpp index 46064bda..83aaa7ef 100644 --- a/client/source/core/ClientApplication.cpp +++ b/client/source/core/ClientApplication.cpp @@ -31,6 +31,7 @@ #include "ClientApplication.hpp" #include "Config.hpp" +#include "Font.hpp" #include "TextureAtlas.hpp" #include "TextureLoader.hpp" @@ -66,9 +67,12 @@ void ClientApplication::init() { initOpenGL(); m_resourceHandler.loadConfigFile("resources/config/textures.xml"); - m_resourceHandler.add("font-default", "resources/fonts/default.ttf"); + m_resourceHandler.add("font-ascii", "texture-font", "resources/textures/font.properties"); m_resourceHandler.add("atlas-blocks"); + // FIXME: Remove this after replacing gk::TextInput in ServerConnectState + m_resourceHandler.add("font-default", "resources/fonts/default.ttf"); + Registry::setInstance(m_registry); // m_stateStack.push(); diff --git a/client/source/gui/Font.cpp b/client/source/gui/Font.cpp new file mode 100644 index 00000000..a7cbd8c2 --- /dev/null +++ b/client/source/gui/Font.cpp @@ -0,0 +1,64 @@ +/* + * ===================================================================================== + * + * 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 +#include + +#include "Font.hpp" + +Font::Font(const std::string &textureName, const std::string &configPath) + : m_texture(gk::ResourceHandler::getInstance().get(textureName)) +{ + m_textureName = textureName; + + std::memset(m_charWidth, 0, sizeof(u8) * 256); + + parseConfig(configPath); +} + +void Font::parseConfig(const std::string &configPath) { + std::ifstream file(configPath); + + std::string line; + while (std::getline(file, line, '\n')) { + if (line.empty()) continue; + + u16 dot = line.find_first_of('.'); + u16 equal = line.find_first_of('='); + + std::string propertyName = line.substr(0, dot); + if (propertyName != "width") + throw EXCEPTION("Unexpected property for font:", propertyName); + + int propertyKey = std::stoi(line.substr(dot + 1, equal - dot - 1)); + u8 propertyValue = std::stoi(line.substr(equal + 1)); + + m_charWidth[propertyKey] = propertyValue; + } +} + diff --git a/client/source/gui/Font.hpp b/client/source/gui/Font.hpp new file mode 100644 index 00000000..8a3056a1 --- /dev/null +++ b/client/source/gui/Font.hpp @@ -0,0 +1,56 @@ +/* + * ===================================================================================== + * + * 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 + * + * ===================================================================================== + */ +#ifndef FONT_HPP_ +#define FONT_HPP_ + +#include + +#include + +namespace gk { + class Texture; +} + +class Font { + public: + Font(const std::string &textureName, const std::string &configPath); + + u8 getCharWidth(u8 c) { return m_charWidth[c]; } + + const std::string &textureName() const { return m_textureName; } // FIXME: Will be removed later + const gk::Texture &texture() const { return m_texture; } + + private: + void parseConfig(const std::string &configPath); + + std::string m_textureName; // FIXME: Will be removed later + gk::Texture &m_texture; + + u8 m_charWidth[256]; +}; + +#endif // FONT_HPP_ diff --git a/client/source/gui/Text.cpp b/client/source/gui/Text.cpp index 15c15bf3..7c9e3912 100644 --- a/client/source/gui/Text.cpp +++ b/client/source/gui/Text.cpp @@ -24,16 +24,14 @@ * * ===================================================================================== */ -#include #include #include "Color.hpp" +#include "Font.hpp" #include "Text.hpp" -Text::Text() : m_texture(gk::ResourceHandler::getInstance().get("texture-font")) { +Text::Text() : m_font(gk::ResourceHandler::getInstance().get("font-ascii")) { m_background.setFillColor(gk::Color::Transparent); - - updateCharWidth(); } void Text::setText(const std::string &text) { @@ -71,38 +69,38 @@ void Text::updateTextSprites() { unsigned int maxX = 0; gk::Color color = gk::Color{70, 70, 70, 255}; for(char c : m_text) { - if (c == '\n' || (m_maxLineLength && x + m_charWidth[(u8)c] >= m_maxLineLength)) { + if (c == '\n' || (m_maxLineLength && x + m_font.getCharWidth(c) >= m_maxLineLength)) { y += 9; x = 0; continue; } - gk::Sprite sprite{"texture-font", 8, 8}; + gk::Sprite sprite{m_font.textureName(), 8, 8}; sprite.setCurrentFrame(c); sprite.setPosition(x + 1, y + 1, 0); sprite.setColor(color); m_textSprites.emplace_back(std::move(sprite)); - x += m_charWidth[(u8)c]; + x += m_font.getCharWidth(c); } x = 0; y = 0; color = m_color; for(char c : m_text) { - if (c == '\n' || (m_maxLineLength && x + m_charWidth[(u8)c] >= m_maxLineLength)) { + if (c == '\n' || (m_maxLineLength && x + m_font.getCharWidth(c) >= m_maxLineLength)) { maxX = std::max(x, maxX); y += 9; x = 0; continue; } - gk::Sprite sprite{"texture-font", 8, 8}; + gk::Sprite sprite{m_font.textureName(), 8, 8}; sprite.setCurrentFrame(c); sprite.setPosition(x, y, 0); if (c == '[') color = Color::Blue; sprite.setColor(color); m_textSprites.emplace_back(std::move(sprite)); - x += m_charWidth[(u8)c]; + x += m_font.getCharWidth(c); } m_size.x = std::max(x, maxX); @@ -114,52 +112,3 @@ void Text::updateTextSprites() { m_background.setSize(backgroundX, backgroundY); } -// 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() { - const int width = m_texture.getSize().x; - const int height = m_texture.getSize().y; - unsigned int *data = new unsigned int[width * height]; - - gk::Texture::bind(&m_texture); - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data); - gk::Texture::bind(nullptr); - - const int charMaxHeight = height / 16; - const int charMaxWidth = width / 16; - - for (int i = 0 ; i < 256 ; ++i) { - 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; - - if ((data[i2 + k2] & 255) != 0) - flag1 = false; - } - - if (!flag1) break; - } - - ++l1; - m_charWidth[i] = 0.5f + l1 * (8.0f / charMaxWidth) + 1; - } - - delete[] data; -} - diff --git a/client/source/gui/Text.hpp b/client/source/gui/Text.hpp index 79fd385d..64a1f70e 100644 --- a/client/source/gui/Text.hpp +++ b/client/source/gui/Text.hpp @@ -32,6 +32,8 @@ #include #include +class Font; + class Text : public gk::Drawable, public gk::Transformable { public: Text(); @@ -55,15 +57,11 @@ class Text : public gk::Drawable, public gk::Transformable { void draw(gk::RenderTarget &target, gk::RenderStates states) const override; void updateTextSprites(); - void updateCharWidth(); std::string m_text; std::vector m_textSprites; - int m_charWidth[256]; - - gk::Texture &m_texture; - gk::VertexBuffer m_vbo; + Font &m_font; gk::Vector2i m_size; gk::Vector2i m_padding{0, 0}; diff --git a/resources/textures/font.properties b/resources/textures/font.properties new file mode 100644 index 00000000..d2892069 --- /dev/null +++ b/resources/textures/font.properties @@ -0,0 +1,256 @@ +width.0=6 +width.1=6 +width.2=6 +width.3=6 +width.4=6 +width.5=6 +width.6=4 +width.7=6 +width.8=6 +width.9=6 +width.10=6 +width.11=6 +width.12=6 +width.13=6 +width.14=6 +width.15=4 +width.16=4 +width.17=6 +width.18=7 +width.19=6 +width.20=6 +width.21=6 +width.22=6 +width.23=6 +width.24=6 +width.25=1 +width.26=1 +width.27=1 +width.28=1 +width.29=1 +width.30=1 +width.31=1 +width.32=4 +width.33=2 +width.34=5 +width.35=6 +width.36=6 +width.37=6 +width.38=6 +width.39=3 +width.40=5 +width.41=5 +width.42=5 +width.43=6 +width.44=2 +width.45=6 +width.46=2 +width.47=6 +width.48=6 +width.49=6 +width.50=6 +width.51=6 +width.52=6 +width.53=6 +width.54=6 +width.55=6 +width.56=6 +width.57=6 +width.58=2 +width.59=2 +width.60=5 +width.61=6 +width.62=5 +width.63=6 +width.64=7 +width.65=6 +width.66=6 +width.67=6 +width.68=6 +width.69=6 +width.70=6 +width.71=6 +width.72=6 +width.73=4 +width.74=6 +width.75=6 +width.76=6 +width.77=6 +width.78=6 +width.79=6 +width.80=6 +width.81=6 +width.82=6 +width.83=6 +width.84=6 +width.85=6 +width.86=6 +width.87=6 +width.88=6 +width.89=6 +width.90=6 +width.91=4 +width.92=6 +width.93=4 +width.94=6 +width.95=6 +width.96=3 +width.97=6 +width.98=6 +width.99=6 +width.100=6 +width.101=6 +width.102=5 +width.103=6 +width.104=6 +width.105=2 +width.106=6 +width.107=5 +width.108=3 +width.109=6 +width.110=6 +width.111=6 +width.112=6 +width.113=6 +width.114=6 +width.115=6 +width.116=4 +width.117=6 +width.118=6 +width.119=6 +width.120=6 +width.121=6 +width.122=6 +width.123=5 +width.124=2 +width.125=5 +width.126=7 +width.127=6 +width.128=6 +width.129=6 +width.130=6 +width.131=6 +width.132=6 +width.133=6 +width.134=6 +width.135=6 +width.136=6 +width.137=6 +width.138=6 +width.139=4 +width.140=6 +width.141=3 +width.142=6 +width.143=6 +width.144=6 +width.145=6 +width.146=6 +width.147=6 +width.148=6 +width.149=6 +width.150=6 +width.151=6 +width.152=6 +width.153=6 +width.154=6 +width.155=6 +width.156=6 +width.157=6 +width.158=4 +width.159=6 +width.160=6 +width.161=3 +width.162=6 +width.163=6 +width.164=6 +width.165=6 +width.166=6 +width.167=6 +width.168=6 +width.169=7 +width.170=6 +width.171=6 +width.172=6 +width.173=2 +width.174=6 +width.175=6 +width.176=8 +width.177=9 +width.178=9 +width.179=6 +width.180=6 +width.181=6 +width.182=8 +width.183=8 +width.184=6 +width.185=8 +width.186=8 +width.187=8 +width.188=8 +width.189=8 +width.190=6 +width.191=6 +width.192=9 +width.193=9 +width.194=9 +width.195=9 +width.196=9 +width.197=9 +width.198=9 +width.199=9 +width.200=9 +width.201=9 +width.202=9 +width.203=9 +width.204=9 +width.205=9 +width.206=9 +width.207=9 +width.208=9 +width.209=9 +width.210=9 +width.211=9 +width.212=9 +width.213=9 +width.214=9 +width.215=9 +width.216=9 +width.217=6 +width.218=9 +width.219=9 +width.220=9 +width.221=5 +width.222=9 +width.223=9 +width.224=8 +width.225=7 +width.226=7 +width.227=8 +width.228=7 +width.229=8 +width.230=8 +width.231=8 +width.232=7 +width.233=8 +width.234=8 +width.235=7 +width.236=9 +width.237=9 +width.238=6 +width.239=7 +width.240=7 +width.241=7 +width.242=7 +width.243=7 +width.244=9 +width.245=6 +width.246=7 +width.247=8 +width.248=7 +width.249=6 +width.250=6 +width.251=9 +width.252=7 +width.253=6 +width.254=7 +width.255=1