-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvgl_character.hpp
More file actions
176 lines (150 loc) · 4.39 KB
/
vgl_character.hpp
File metadata and controls
176 lines (150 loc) · 4.39 KB
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#ifndef VGL_CHARACTER_HPP
#define VGL_CHARACTER_HPP
#include "vgl_extern_freetype.hpp"
#include "vgl_image_2d_gray.hpp"
#include "vgl_texture_2d.hpp"
namespace vgl
{
/// One character.
class Character
{
private:
/// Texture for the glyph.
Texture2DUptr m_texture;
/// Glyph rectangle offset for this character.
vec2 m_quad_offset;
/// Glyph rectangle size for this character.
vec2 m_quad_size;
/// Index in font.
unsigned m_font_index = 0;
/// Typographic left.
float m_left = 0.0f;
/// Typographic top.
float m_top = 0.0f;
/// Advance value X.
float m_advance_x = 0.0f;
private:
/// Deleted copy constructor.
Character(const Character&) = delete;
/// Deleted assignment.
Character& operator=(const Character&) = delete;
public:
/// Default constructor.
constexpr explicit Character() noexcept = default;
/// Constructor.
///
/// \param idx Index in font.
/// \param bitmap Glyph bitmap.
/// \param left Typographic left value.
/// \param top Typographic top value.
/// \param advx Advance value (x).
/// \param advy Advance value (y).
/// \param base_size Base font size.
/// \param buf Geometry buffer to insert to.
explicit Character(unsigned idx, const FT_Bitmap *bitmap, float left, float top, float advx, float base_size) :
m_font_index(idx),
m_left(left),
m_top(top),
m_advance_x(advx)
{
unsigned bw = bitmap->width + 2;
unsigned bh = bitmap->rows + 2;
unsigned extra_width = (bw % 4) ? (4 - (bw % 4)) : 0;
unsigned extra_height = (bh % 4) ? (4 - (bh % 4)) : 0;
Image2DGray img(bw + extra_width, bh + extra_height);
img.clear(0, 0.0f);
for(unsigned ii = 0; (bitmap->width > ii); ++ii)
{
for(unsigned jj = 0; (bitmap->rows > jj); ++jj)
{
const uint8_t *rptr = reinterpret_cast<const uint8_t*>(bitmap->buffer) + (jj * bitmap->width) + ii;
img.setPixel(ii + 1, img.getHeight() - 2 - jj, static_cast<float>(*rptr) * (1.0f / 255.0f));
}
}
m_texture = Texture2D::create(img);
{
float fs = static_cast<float>(base_size);
float fw = static_cast<float>(img.getWidth()) / fs;
float fh = static_cast<float>(img.getHeight()) / fs;
float fl = m_left - (1.0f / fs)/* + static_cast<float>(extra_width) / fs*/;
float ft = m_top + (1.0f / fs)/* + static_cast<float>(extra_height) / fs*/;
m_quad_offset = vec2(fl, ft - fh);
m_quad_size = vec2(fw, fh);
}
}
/// Move constructor.
///
/// \param other Source object.
Character(Character&& other) noexcept :
m_texture(move(other.m_texture)),
m_quad_offset(other.m_quad_offset),
m_quad_size(other.m_quad_size),
m_font_index(other.m_font_index),
m_left(other.m_left),
m_top(other.m_top),
m_advance_x(other.m_advance_x)
{
}
public:
/// Accessor.
///
/// \return X advance.
float getAdvanceX() const noexcept
{
return m_advance_x;
}
/// Accessor.
///
/// \return Index in font.
unsigned getFontIndex() const noexcept
{
return m_font_index;
}
/// Accessor.
///
/// \return Character rectangle offset.
const vec2& getQuadOffset() const noexcept
{
return m_quad_offset;
}
/// Accessor.
///
/// \return Character rectangle size.
const vec2& getQuadSize() const noexcept
{
return m_quad_size;
}
/// Accessor.
///
/// \return Texture.
const Texture2D& getTexture() const
{
VGL_ASSERT(m_texture);
return *(m_texture.get());
}
public:
/// Conversion to bool.
///
/// \return Flag signifying if the character has been created.
constexpr operator bool() const noexcept
{
return m_texture;
}
/// Move operator.
///
/// \param other Source object.
/// \return This object.
Character& operator=(Character&& other) noexcept
{
m_texture = move(other.m_texture);
m_quad_offset = other.m_quad_offset;
m_quad_size = other.m_quad_size;
m_font_index = other.m_font_index;
m_left = other.m_left;
m_top = other.m_top;
m_advance_x = other.m_advance_x;
return *this;
}
};
}
#endif