22 #include FT_FREETYPE_H
28 #if defined(_DEBUG) && defined(_WINDOWS)
29 #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
37 m_virtual_screen_height(0.0
f)
42 const float &virtual_screen_height,
44 : m_glyph_height(glyph_height),
45 m_virtual_screen_height(virtual_screen_height),
46 m_font_name(font_name)
50 Font_FT::Glyph::Glyph()
59 const Point2i &position,
60 const Point2i &total_size)
65 throw Error(
"FT_Load_Char(...) failed.");
70 throw Error(
"FT_Get_Glyph(...) failed.");
74 m_glyph_width =
int(glyph->
advance.
x) / (65536.0f * vratio);
75 m_upper_left_point.x = bglyph->
left / vratio;
76 m_upper_left_point.y = (ascent - bglyph->
top) / vratio;
78 m_lower_right_point.y = (ascent - bglyph->
top + bglyph->
bitmap.
rows) / vratio;
80 m_upper_left_texel.x = float(position.x) / total_size.x;
81 m_upper_left_texel.y = float(position.y) / total_size.y;
82 m_lower_right_texel.x = float(position.x + bglyph->
bitmap.
width) / total_size.x;
83 m_lower_right_texel.y = float(position.y + bglyph->
bitmap.
rows) / total_size.y;
92 const float x =
int(position.x * vratio + 0.5f) / vratio;
93 const float y =
int(position.y * vratio + 0.5f) / vratio;
95 Quadrilateral<Vertex2f_Texture> rect(
96 (Vertex2f_Texture(Point2f(m_upper_left_point.x + x, m_upper_left_point.y + y), m_upper_left_texel)) ,
97 (Vertex2f_Texture(Point2f(m_upper_left_point.x + x, m_lower_right_point.y + y), Point2f(m_upper_left_texel.x, m_lower_right_texel.y))) ,
98 (Vertex2f_Texture(Point2f(m_lower_right_point.x + x, m_lower_right_point.y + y), m_lower_right_texel)) ,
99 (Vertex2f_Texture(Point2f(m_lower_right_point.x + x, m_upper_left_point.y + y), Point2f(m_lower_right_texel.x, m_upper_left_texel.y))) );
107 const Vector3f scaled_right = (m_lower_right_point.x - m_upper_left_point.x) * right;
108 const Vector3f scaled_down = (m_lower_right_point.y - m_upper_left_point.y) * down;
110 const Point3f &ul = position + m_upper_left_point.x * right + m_upper_left_point.y * down;
111 const Point3f ll = ul + scaled_down;
112 const Point3f lr = ll + scaled_right;
113 const Point3f ur = ul + scaled_right;
115 Quadrilateral<Vertex3f_Texture> rect(
116 (Vertex3f_Texture(ul, m_upper_left_texel)) ,
117 (Vertex3f_Texture(ll, Point2f(m_upper_left_texel.x, m_lower_right_texel.y))) ,
118 (Vertex3f_Texture(lr, m_lower_right_texel)) ,
119 (Vertex3f_Texture(ur, Point2f(m_lower_right_texel.x, m_upper_left_texel.y))) );
132 const float &glyph_height,
133 const float &virtual_screen_height)
137 float(
get_Window().get_height()) : virtual_screen_height,
140 m_font_height(glyph_height),
144 m_vratio(
get_Window().get_height() / get_virtual_screen_height())
147 ZENI_LOGD((
"Generating font '" + filepath +
"', size " +
ftoa(m_font_height) +
", ratio " +
ftoa(m_vratio)).c_str());
152 float max_width = 0.0f,
width = 0.0f;
153 unsigned int pos = 0;
154 const unsigned int size =
static_cast<unsigned int>(text.
size());
156 for(; pos <
size; ++pos)
157 if(text[pos] !=
'\r' && text[pos] !=
'\n')
158 width += m_glyph[
int(text[pos])].get_glyph_width();
169 const float &x = position.
x;
170 const float &y = position.
y;
177 float cx, x_diff, cy =
y;
186 for(
unsigned int j = i;
j < text.
size(); ++
j) {
187 if(text[
j] ==
'\r' || text[
j] ==
'\n')
190 x_diff -= m_glyph[
int(text[
j])].get_glyph_width();
199 for(; i < text.
size(); ++
i) {
200 if(text[i] ==
'\r' && i+1 < text.
size() && text[i+1] ==
'\n')
203 if(text[i] ==
'\r' || text[i] ==
'\n') {
209 m_glyph[
int(text[i])].render(vr,
Point2f(cx, cy), m_vratio);
210 cx += m_glyph[
int(text[i])].get_glyph_width();
227 Point3f pos, vertical_pos = position;
237 for(
unsigned int j = i;
j < text.
size(); ++
j) {
238 if(text[
j] ==
'\r' || text[
j] ==
'\n')
241 x_diff -= m_glyph[
int(text[
j])].get_glyph_width();
245 pos += x_diff / 2.0f *
right;
247 pos += x_diff *
right;
250 for(; i < text.
size(); ++
i) {
251 if(text[i] ==
'\r' && i+1 < text.
size() && text[i+1] ==
'\n')
254 if(text[i] ==
'\r' || text[i] ==
'\n') {
256 vertical_pos += m_font_height * down;
260 m_glyph[
int(text[i])].render(vr, pos, right, down);
261 pos += m_glyph[
int(text[i])].get_glyph_width() *
right;
270 void Font_FT::init(
const String &filepath) {
286 ZENI_LOGE(
"FT_Init_FreeType(...) failed.");
287 throw Error(
"FT_Init_FreeType(...) failed.");
289 ZENI_LOGD(
"FT_Init_FreeType(...) success.");
300 throw Error(
"FT_Open_Face(...) failed.");
305 ZENI_LOGE(
"FT_Set_Pixel_Sizes(...) failed.");
306 throw Error(
"FT_Set_Pixel_Sizes(...) failed.");
308 ZENI_LOGD(
"FT_Set_Pixel_Sizes(...) success.");
311 std::vector<Image> glyph(96);
313 for(
int i = 32;
i != 128; ++
i) {
314 Image &
img = glyph[
i - 32];
315 img = gen_glyph(face,
char(
i));
316 if(img.width() >= maxsz.x)
317 maxsz.x = img.width() + 1;
318 if(img.height() >= maxsz.y)
319 maxsz.y = img.height() + 1;
322 Image glyphs(Point2i(next_power_of_two(10 * maxsz.x), next_power_of_two(10 * maxsz.y)),
Image::Luminance_Alpha,
false);
323 m_glyph.reserve(256);
325 for(
int i = 0;
i != 96; ++
i) {
326 const Point2i pos((
i % 10) * maxsz.x, (
i / 10) * maxsz.y);
327 glyphs.blit(pos, glyph[
i]);
328 m_glyph.push_back(Glyph(face,
char(i + 32), m_ascent, m_vratio, pos, glyphs.
size()));
333 ZENI_LOGD(
"Generating Texture from glyphs.");
342 ZENI_LOGD(
"Calling FT_Done_FreeType(...).");
346 int Font_FT::next_power_of_two(
const int &
a) {
348 while(rval<a) rval<<=1;
352 Image Font_FT::gen_glyph(
FT_Face &face,
const char &ch) {
356 throw Error(
"FT_Load_Char(...) failed.");
364 throw Error(
"FT_Get_Glyph(...) failed.");
371 if(bglyph->
top > m_ascent)
372 m_ascent = bglyph->
top;
386 image_data[2 * pixel] = 0xFF;
387 image_data[2 * pixel + 1] = bglyph->
bitmap.
buffer[pixel];
const FT_Byte * memory_base
static String & load_asset(String &memory, const String &filename)
Load a file into memory.
The Video Rendering Singleton.
static void render(const Vertex_Buffer_Macrorenderer ¯orenderer, std::vector< Vertex_Buffer::Vertex_Buffer_Range * > &descriptors)
EGLSurface EGLint EGLint EGLint EGLint height
GLboolean GLboolean GLboolean GLboolean a
const char * c_str() const
Font_FT()
Instantiate a new Font with a call to get_Video().create_Font()
FT_Done_FreeType(FT_Library library)
virtual float get_text_width(const String &text) const
Get the width of text rendering using this font. Approximately text_height * text.length() / 2.0f.
FT_Init_FreeType(FT_Library *alibrary)
FT_Set_Pixel_Sizes(FT_Face face, FT_UInt pixel_width, FT_UInt pixel_height)
A 3D Point represented with floats.
void apply_Texture(const String &name)
Apply a texture by name.
A Featureful 3-Space Vector Class.
String ftoa(const float &number)
virtual Texture * create_Texture(const Image &image)=0
Function for creating a Texture from an Image.
EGLSurface EGLint EGLint EGLint width
virtual void unapply_Texture()=0
Unapply a texture.
void ZENI_LOGD(const Zeni::String &str)
FT_Load_Char(FT_Face face, FT_ULong char_code, FT_Int32 load_flags)
virtual void set_Color(const Color &color)=0
Set the current color.
void ZENI_LOGE(const Zeni::String &str)
#define MAXIMUM_VIRTUAL_SCREEN_HEIGHT
Window & get_Window()
Get access to the singleton.
FT_Get_Glyph(FT_GlyphSlot slot, FT_Glyph *aglyph)
EGLSurface EGLint EGLint y
Font()
Instantiate a new Font with a call to get_Video().create_Font()
uint8_t Uint8
An unsigned 8-bit integer type.
FT_Open_Face(FT_Library library, const FT_Open_Args *args, FT_Long face_index, FT_Face *aface)
const Color & get_Color() const
Get the current color.
Video & get_Video()
Get access to the singleton.
float get_text_height() const
Get the height of the font. The width is usually half the height, by default.
#define MINIMUM_VIRTUAL_SCREEN_HEIGHT
FT_Done_Face(FT_Face face)
A 2D Point represented with floats.
FT_Done_Glyph(FT_Glyph glyph)
virtual void render_text(const String &text, const Point2f &position, const Color &color, const JUSTIFY &justify=ZENI_LEFT) const
Render text at screen position (x, y), with justification JUSTIFY.