aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/Font.cpp117
-rw-r--r--src/common/Font.hpp43
-rw-r--r--src/games/minesweeper/Minesweeper.cpp13
-rw-r--r--src/games/minesweeper/Minesweeper.hpp9
4 files changed, 181 insertions, 1 deletions
diff --git a/src/common/Font.cpp b/src/common/Font.cpp
new file mode 100644
index 0000000..31a6720
--- /dev/null
+++ b/src/common/Font.cpp
@@ -0,0 +1,117 @@
+#include <common/Font.hpp>
+
+#include <fstream>
+#include <iostream>
+
+
+Font::~Font()
+{
+ Deinit();
+}
+
+
+bool
+Font::Init(const char* path, int font_size)
+{
+ std::ifstream file(path, std::ios::in|std::ios::binary|std::ios::ate);
+ if (!file.is_open()) {
+ return false;
+ }
+
+
+ std::streampos end = file.tellg();
+ size_t size = static_cast<size_t>(end);
+ char *content = new char[size + 1];
+
+ file.seekg(0, std::ios::beg);
+ file.read(content, end);
+ file.close();
+ content[size] = '\0';
+
+
+ // set font info
+ if (!stbtt_InitFont(&m_font_info, (unsigned char*)content, 0))
+ {
+ std::cout << "stbtt_InitFont failed.\n";
+ printf("stbtt_InitFont failed\n");
+ delete[] content;
+ return false;
+ }
+
+
+ // font settings (scale + vmetrics)
+ float scale = stbtt_ScaleForPixelHeight(&m_font_info, (float)font_size);
+ int baseline, ascent, descent, line_gap;
+ stbtt_GetFontVMetrics(&m_font_info, &ascent, &descent, &line_gap);
+ baseline = int(scale * (float)-descent);
+ ascent = int(scale * (float)ascent);
+ descent = int(scale * (float)descent);
+ line_gap = int(scale * (float)line_gap);
+
+
+ m_font_scale = scale;
+ m_font_baseline = baseline;
+ m_font_yadvance = ascent - descent + line_gap;
+ m_file_content = content;
+
+
+ return true;
+}
+
+
+void
+Font::LoadGlyph(Glyph& glyph, uint32_t codepoint)
+{
+ int bbx0, bby0, bbx1, bby1;
+ stbtt_GetCodepointBitmapBox(&m_font_info, (int)codepoint, m_font_scale, m_font_scale, &bbx0, &bby0, &bbx1, &bby1);
+ int width = bbx1 - bbx0;
+ int height = bby1 - bby0;
+
+
+ size_t size = size_t(width * height);
+ uint8_t* bitmap_flipped = new uint8_t[size];
+ uint8_t* bitmap_correct = new uint8_t[size];
+
+
+ stbtt_MakeCodepointBitmap(&m_font_info, bitmap_flipped, width, height, width, m_font_scale, m_font_scale, (int)codepoint);
+
+ uint8_t* dest = bitmap_correct;
+ for (int y = 0; y < height; ++y)
+ {
+ uint8_t* src = bitmap_flipped + size_t((height-1-y)*width);
+ for (int x = 0; x < width; ++x)
+ {
+ *dest++ = *src++;
+ }
+ }
+ delete[] bitmap_flipped;
+
+ glyph.bitmap.width = width;
+ glyph.bitmap.height = height;
+ glyph.bitmap.pixels = std::unique_ptr<uint8_t>(bitmap_correct);
+
+
+ int xadvance;
+ int left_side_bearing;
+ stbtt_GetCodepointHMetrics(&m_font_info, (int)codepoint, &xadvance, &left_side_bearing);
+ xadvance = (int)(m_font_scale * (float)xadvance);
+ left_side_bearing = (int)(m_font_scale * (float)left_side_bearing);
+
+
+ glyph.xoff = static_cast<int>(m_font_scale * (float)bbx0) + left_side_bearing;
+ glyph.yoff = -bby1;
+ glyph.xadvance = xadvance;
+
+}
+
+
+void
+Font::Deinit()
+{
+ if (m_file_content) {
+ delete[] m_file_content;
+ m_file_content = nullptr;
+ }
+}
+
+
diff --git a/src/common/Font.hpp b/src/common/Font.hpp
new file mode 100644
index 0000000..a594add
--- /dev/null
+++ b/src/common/Font.hpp
@@ -0,0 +1,43 @@
+#pragma once
+
+#include <filesystem>
+#include <stb_truetype.h>
+
+
+struct MonoBitmap {
+ int32_t width;
+ int32_t height;
+ std::unique_ptr<uint8_t> pixels;
+};
+
+
+struct Glyph {
+ int32_t xoff;
+ int32_t yoff;
+ int32_t xadvance;
+ MonoBitmap bitmap;
+};
+
+
+class Font {
+public:
+ ~Font();
+
+ bool Init(const char* path, int font_size);
+ void Deinit();
+
+ void LoadGlyph(Glyph& glyph, uint32_t codepoint);
+
+
+private:
+ const char* m_file_content = nullptr;
+
+ float m_font_scale;
+ int m_font_baseline;
+ int m_font_yadvance;
+
+ stbtt_fontinfo m_font_info;
+ Glyph m_glyphs['~' - ' ' + 1];
+};
+
+
diff --git a/src/games/minesweeper/Minesweeper.cpp b/src/games/minesweeper/Minesweeper.cpp
index 6dc77a4..abb9515 100644
--- a/src/games/minesweeper/Minesweeper.cpp
+++ b/src/games/minesweeper/Minesweeper.cpp
@@ -25,8 +25,11 @@ Minesweeper::Minesweeper()
m_CellOuterViewSize = {cell_size, cell_size};
m_CellInnerViewSize = {cell_size_without_border, cell_size_without_border};
+ m_Font.Init("fonts/dejavu_ttf/DejaVuSansMono.ttf", 32);
+ for (uint32_t i = 0; i < m_DigitGlyphs.size(); ++i) {
+ m_Font.LoadGlyph(m_DigitGlyphs[i], i + '0');
+ }
- // Todo: assert various stuff
Reinit();
}
@@ -278,6 +281,14 @@ void Minesweeper::DrawBoard(RenderGroup &render_group) {
};
+ // Temporary: Drawing Glyph Test
+ render_group.PushBitmap(
+ {100.0f, 100.0f, 10.0f},
+ m_DigitGlyphs[1].bitmap.width,
+ m_DigitGlyphs[1].bitmap.height,
+ m_DigitGlyphs[1].bitmap.pixels.get());
+
+
for (int32_t y = 0; y < m_MapHeight; y++) {
for (int32_t x = 0; x < m_MapWidth; x++) {
V2F32 world_pos = {
diff --git a/src/games/minesweeper/Minesweeper.hpp b/src/games/minesweeper/Minesweeper.hpp
index 4906464..b081806 100644
--- a/src/games/minesweeper/Minesweeper.hpp
+++ b/src/games/minesweeper/Minesweeper.hpp
@@ -1,6 +1,10 @@
#pragma once
#include <games/Game.hpp>
+#include <common/Font.hpp>
+
+#include <array>
+
namespace std {
template <>
@@ -13,6 +17,7 @@ namespace std {
};
}
+
enum class MinesweeperRunState {
Resume,
Pause,
@@ -21,6 +26,7 @@ enum class MinesweeperRunState {
Exit
};
+
class Minesweeper : public Game {
public:
Minesweeper();
@@ -76,6 +82,9 @@ class Minesweeper : public Game {
uint32_t m_IsFlaggedBitmap[MAX_MAP_HEIGHT] {};
uint32_t m_IsMineBitmap[MAX_MAP_HEIGHT] {};
int32_t m_AdjacentMineCounters[MAX_MAP_WIDTH * MAX_MAP_HEIGHT] {};
+
+ Font m_Font;
+ std::array<Glyph, 9> m_DigitGlyphs;
};