1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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.w = width;
glyph.bitmap.h = 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;
}
}
|