diff options
Diffstat (limited to 'src/common/Font.cpp')
| -rw-r--r-- | src/common/Font.cpp | 117 |
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; + } +} + + |
