aboutsummaryrefslogtreecommitdiff
path: root/src/common/Font.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/Font.cpp')
-rw-r--r--src/common/Font.cpp117
1 files changed, 117 insertions, 0 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;
+ }
+}
+
+