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; +    } +} + +  | 
