summaryrefslogtreecommitdiff
path: root/src/graphics
diff options
context:
space:
mode:
authorEkaitz Zarraga <ekaitz@elenq.tech>2022-12-09 19:43:16 +0100
committerEkaitz Zarraga <ekaitz@elenq.tech>2022-12-09 19:43:16 +0100
commit2b6cd04c1fcf9807b6da9aa03e9920c28780db2c (patch)
treee31e647762d5827c1b95006af3233af96146a608 /src/graphics
parent30f488cdcb88dad5dd1df425588cb6a7fd206bb5 (diff)
Add basic bitmap font/text support
Diffstat (limited to 'src/graphics')
-rw-r--r--src/graphics/font.cpp86
-rw-r--r--src/graphics/font.h35
2 files changed, 121 insertions, 0 deletions
diff --git a/src/graphics/font.cpp b/src/graphics/font.cpp
new file mode 100644
index 0000000..42176b2
--- /dev/null
+++ b/src/graphics/font.cpp
@@ -0,0 +1,86 @@
+#include "font.h"
+
+using namespace Graphics;
+
+// Font
+
+Font::Font(const sf::Texture &texture, const std::string &mapping,
+ unsigned int numrows, unsigned int numcols)
+ : tex_(texture)
+ , mapping_(mapping)
+ , numrows_(numrows)
+ , numcols_(numcols)
+{
+ sf::Vector2u totalSize = tex_.getSize();
+ sf::Vector2f totalSize_f (totalSize.x, totalSize.y);
+ glyphSize_ = sf::Vector2f( totalSize.x / numcols_, totalSize.y / numrows_ );
+}
+
+std::array<sf::Vector2f, 4> Font::getGlyphMapping(const char ch){
+ unsigned int pos = static_cast<unsigned int>( mapping_.find_first_of(ch));
+ if (pos == std::string::npos){
+ // TODO: Error handling!
+ pos = 0;
+ }
+ unsigned int x = pos % numcols_;
+ unsigned int y = (pos - x) / numcols_;
+
+ sf::Vector2f basePos(x*glyphSize_.x, y*glyphSize_.y);
+
+ // 1 --- 2
+ // | |
+ // 4 --- 3
+ return std::array<sf::Vector2f,4> {
+ basePos,
+ basePos + sf::Vector2f( glyphSize_.x, 0 ),
+ basePos + glyphSize_,
+ basePos + sf::Vector2f( 0, glyphSize_.y ),
+ };
+}
+
+sf::Vector2f Font::getGlyphSize(){
+ return glyphSize_;
+}
+
+const sf::Texture * Font::getTexture(){
+ return &tex_;
+}
+
+
+
+
+// Text
+
+Text::Text(Font &font, const std::string &text)
+ : font_(font)
+ , text_(text)
+ , vertices_(sf::Quads, text.size()*4)
+{
+ unsigned int length = vertices_.getVertexCount();
+ sf::Vector2f glyphSize = font_.getGlyphSize();
+ // TODO: this is the simplest rendering way: everything in one line
+ // we should improve this to make it handle newlines or max witdths
+ for(unsigned int i=0; i < length; i=i+4){
+ vertices_[i+0].position = sf::Vector2f(glyphSize.x * i/4, 0);
+ vertices_[i+1].position = sf::Vector2f(glyphSize.x * (i/4 + 1), 0);
+ vertices_[i+2].position = sf::Vector2f(glyphSize.x * (i/4 + 1), glyphSize.y);
+ vertices_[i+3].position = sf::Vector2f(glyphSize.x * i/4, glyphSize.y);
+
+ std::array<sf::Vector2f, 4> glyph = font_.getGlyphMapping(text_[i/4]);
+
+ vertices_[i+0].texCoords = glyph[0];
+ vertices_[i+1].texCoords = glyph[1];
+ vertices_[i+2].texCoords = glyph[2];
+ vertices_[i+3].texCoords = glyph[3];
+ }
+}
+
+void Text::draw(sf::RenderTarget& target, sf::RenderStates states) const
+{
+ // TODO: only repaint if needed: when repainting is needed
+ // vertices_.clear() and fun
+ states.transform *= getTransform();
+ states.texture = font_.getTexture();
+ // you may also override states.shader or states.blendMode if you want
+ target.draw(vertices_, states);
+}
diff --git a/src/graphics/font.h b/src/graphics/font.h
new file mode 100644
index 0000000..9a8e919
--- /dev/null
+++ b/src/graphics/font.h
@@ -0,0 +1,35 @@
+#ifndef GRAPHICS_FONT_H
+#define GRAPHICS_FONT_H
+
+#include<string>
+#include<array>
+#include"SFML/Graphics.hpp"
+
+namespace Graphics {
+ class Font {
+ private:
+ const sf::Texture &tex_;
+ const std::string mapping_;
+ const unsigned int numrows_, numcols_;
+ sf::Vector2f glyphSize_;
+ public:
+ Font(const sf::Texture &texture, const std::string &mapping,
+ unsigned int numrows, unsigned int numcols);
+ std::array<sf::Vector2f,4> getGlyphMapping(const char ch);
+ sf::Vector2f getGlyphSize();
+ const sf::Texture *getTexture();
+ };
+
+ class Text : public sf::Drawable, public sf::Transformable {
+ private:
+ Font &font_;
+ const std::string text_;
+ sf::VertexArray vertices_;
+ public:
+ Text(Font &font, const std::string &text);
+ virtual void draw(sf::RenderTarget& target,
+ sf::RenderStates states) const override;
+ };
+}
+
+#endif // GRAPHICS_FONT_H