add initial Font class
This commit is contained in:
parent
d37ac4494a
commit
98fcfdbc04
91
src/gui/Font.cc
Normal file
91
src/gui/Font.cc
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#include "Font.h"
|
||||||
|
|
||||||
|
#define round_up_26_6(val) (((val) + 63) >> 6u)
|
||||||
|
|
||||||
|
static FT_Library ft_library_handle;
|
||||||
|
static bool ft_initialized;
|
||||||
|
|
||||||
|
bool Initialize_FreeType()
|
||||||
|
{
|
||||||
|
if (ft_initialized)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FT_Init_FreeType(&ft_library_handle) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ft_initialized = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Font::load(const char * fname, int size)
|
||||||
|
{
|
||||||
|
if (!Initialize_FreeType())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FT_New_Face(ft_library_handle, fname, 0, &m_face) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FT_Set_Pixel_Sizes(m_face, 0, size);
|
||||||
|
|
||||||
|
return preload_glyphs();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Font::preload_glyphs()
|
||||||
|
{
|
||||||
|
static const char preload_glyph_list[] = "HMgjqxy_|^";
|
||||||
|
|
||||||
|
int max_top = -9999;
|
||||||
|
int min_bottom = 9999;
|
||||||
|
m_advance = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0u; i < sizeof(preload_glyph_list) - 1u; i++)
|
||||||
|
{
|
||||||
|
std::shared_ptr<Glyph> g = get_glyph(preload_glyph_list[i]);
|
||||||
|
if (g == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (m_face->glyph->bitmap_top > max_top)
|
||||||
|
{
|
||||||
|
max_top = m_face->glyph->bitmap_top;
|
||||||
|
}
|
||||||
|
int bitmap_bottom = m_face->glyph->bitmap_top - m_face->glyph->bitmap.rows;
|
||||||
|
if (bitmap_bottom < min_bottom)
|
||||||
|
{
|
||||||
|
min_bottom = bitmap_bottom;
|
||||||
|
}
|
||||||
|
if (g->get_advance() > m_advance)
|
||||||
|
{
|
||||||
|
m_advance = g->get_advance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_line_height = round_up_26_6(m_face->size->metrics.height);
|
||||||
|
m_baseline_offset = (m_line_height - (max_top - min_bottom)) / 2 - min_bottom;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Glyph> Font::get_glyph(FT_ULong character)
|
||||||
|
{
|
||||||
|
auto it = m_glyphs.find(character);
|
||||||
|
if (it != m_glyphs.end())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
std::shared_ptr<Glyph> glyph = std::make_shared<Glyph>();
|
||||||
|
if (!glyph->load(m_face, character))
|
||||||
|
{
|
||||||
|
glyph = nullptr;
|
||||||
|
}
|
||||||
|
m_glyphs[character] = glyph;
|
||||||
|
return glyph;
|
||||||
|
}
|
24
src/gui/Font.h
Normal file
24
src/gui/Font.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef FONT_H
|
||||||
|
#define FONT_H
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <memory>
|
||||||
|
#include "Glyph.h"
|
||||||
|
|
||||||
|
class Font
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool load(const char * fname, int size);
|
||||||
|
std::shared_ptr<Glyph> get_glyph(FT_ULong character);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool preload_glyphs();
|
||||||
|
|
||||||
|
FT_Face m_face;
|
||||||
|
std::unordered_map<FT_ULong, std::shared_ptr<Glyph>> m_glyphs;
|
||||||
|
int m_advance;
|
||||||
|
int m_line_height;
|
||||||
|
int m_baseline_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user