diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/Font.cpp | 90 | ||||
| -rw-r--r-- | src/common/Font.hpp | 25 | 
2 files changed, 80 insertions, 35 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; +} diff --git a/src/common/Font.hpp b/src/common/Font.hpp index 91afe06..af4ddb5 100644 --- a/src/common/Font.hpp +++ b/src/common/Font.hpp @@ -1,10 +1,12 @@  #pragma once -#include <filesystem> +#include <common/defs.hpp>  #include <stb_truetype.h> +#include <memory> -struct MonoBitmap { + +struct AlphaBitmap {      int32_t w;      int32_t h;      std::unique_ptr<uint8_t> pixels; @@ -15,7 +17,7 @@ struct Glyph {      int32_t xoff;      int32_t yoff;      int32_t xadvance; -    MonoBitmap bitmap; +    AlphaBitmap bitmap;  }; @@ -24,12 +26,22 @@ public:      ~Font();      bool Init(const char* path, int font_size); -    void Deinit(); +    AlphaBitmap& GetAlphaBitmap(char32_t c); +    Glyph& GetGlyph(char32_t c); + + -    void LoadGlyph(Glyph& glyph, uint32_t codepoint); +private: +    bool ReadFile(const char* path); +    void LoadGlyph(Glyph& glyph, char32_t c);  private: +    static constexpr char first_ascii_ch = ' '; +    static constexpr char last_ascii_ch = '~'; +    static constexpr char ascii_glyph_count = last_ascii_ch - first_ascii_ch + 1; + +      const char* m_file_content = nullptr;      float m_font_scale; @@ -37,7 +49,8 @@ private:      int m_font_yadvance;      stbtt_fontinfo m_font_info; -    Glyph m_glyphs['~' - ' ' + 1]; +    Glyph m_glyphs[ascii_glyph_count]; +    Glyph m_fail_glyph;  };  | 
