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.cpp90
1 files changed, 61 insertions, 29 deletions
diff --git a/src/common/Font.cpp b/src/common/Font.cpp
index b5b177c..82f6ad8 100644
--- a/src/common/Font.cpp
+++ b/src/common/Font.cpp
@@ -2,44 +2,40 @@
#include <fstream>
#include <iostream>
+#include <cstring>
-Font::~Font()
+static inline bool
+is_ch_ascii(char32_t ch)
{
- Deinit();
+ bool result = ch >= ' ' && ch <= '~';
+ return result;
}
+Font::~Font()
+{
+ delete[] m_file_content;
+}
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()) {
+ if (!ReadFile(path)) {
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))
+ if (!stbtt_InitFont(&m_font_info, (unsigned char*)m_file_content, 0))
{
std::cout << "stbtt_InitFont failed.\n";
- printf("stbtt_InitFont failed\n");
- delete[] content;
+ delete[] m_file_content;
+ m_file_content = nullptr;
return false;
}
- // font settings (scale + vmetrics)
+ // set 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);
@@ -49,21 +45,48 @@ Font::Init(const char* path, int font_size)
line_gap = int(scale * (float)line_gap);
+ // init members
m_font_scale = scale;
m_font_baseline = baseline;
m_font_yadvance = ascent - descent + line_gap;
- m_file_content = content;
+
+
+ // load glyphs
+ for (char c = first_ascii_ch; c <= last_ascii_ch; ++c) {
+ LoadGlyph(m_glyphs[c-first_ascii_ch], static_cast<char32_t>(c));
+ }
+ memset((void*)&m_fail_glyph, 0, sizeof(m_fail_glyph));
return true;
}
+bool
+Font::ReadFile(const char* path)
+{
+ 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';
+
+ m_file_content = content;
+ return m_file_content;
+}
void
-Font::LoadGlyph(Glyph& glyph, uint32_t codepoint)
+Font::LoadGlyph(Glyph& glyph, char32_t c)
{
int bbx0, bby0, bbx1, bby1;
- stbtt_GetCodepointBitmapBox(&m_font_info, (int)codepoint, m_font_scale, m_font_scale, &bbx0, &bby0, &bbx1, &bby1);
+ stbtt_GetCodepointBitmapBox(&m_font_info, (int)c, m_font_scale, m_font_scale, &bbx0, &bby0, &bbx1, &bby1);
int width = bbx1 - bbx0;
int height = bby1 - bby0;
@@ -73,7 +96,7 @@ Font::LoadGlyph(Glyph& glyph, uint32_t codepoint)
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);
+ stbtt_MakeCodepointBitmap(&m_font_info, bitmap_flipped, width, height, width, m_font_scale, m_font_scale, (int)c);
uint8_t* dest = bitmap_correct;
for (int y = 0; y < height; ++y)
@@ -93,7 +116,7 @@ Font::LoadGlyph(Glyph& glyph, uint32_t codepoint)
int xadvance;
int left_side_bearing;
- stbtt_GetCodepointHMetrics(&m_font_info, (int)codepoint, &xadvance, &left_side_bearing);
+ stbtt_GetCodepointHMetrics(&m_font_info, (int)c, &xadvance, &left_side_bearing);
xadvance = (int)(m_font_scale * (float)xadvance);
left_side_bearing = (int)(m_font_scale * (float)left_side_bearing);
@@ -104,14 +127,23 @@ Font::LoadGlyph(Glyph& glyph, uint32_t codepoint)
}
-
-void
-Font::Deinit()
+AlphaBitmap&
+Font::GetAlphaBitmap(char32_t c)
{
- if (m_file_content) {
- delete[] m_file_content;
- m_file_content = nullptr;
+ if (is_ch_ascii(c)) {
+ return m_glyphs[c - first_ascii_ch].bitmap;
}
+
+ return m_fail_glyph.bitmap;
}
+Glyph&
+Font::GetGlyph(char32_t c)
+{
+ if (is_ch_ascii(c)) {
+ return m_glyphs[c - first_ascii_ch];
+ }
+
+ return m_fail_glyph;
+}