4 #include "client/client.h"
5 #include "client/font.h"
21 Character chars[NUM_CHARS];
28 } __attribute__((packed)) VertexFontPosition;
33 } __attribute__((packed)) VertexFontTextureCoordinates;
37 VertexFontPosition position;
38 VertexFontTextureCoordinates textureCoordinates;
39 } __attribute__((packed)) VertexFont;
41 static VertexAttribute vertex_attributes[2] = {
46 .size = sizeof(VertexFontPosition),
52 .size = sizeof(VertexFontTextureCoordinates),
56 static VertexLayout vertex_layout = {
57 .attributes = vertex_attributes,
59 .size = sizeof(VertexFont),
64 if (FT_Init_FreeType(&font.library)) {
65 fprintf(stderr, "Failed to initialize Freetype\n");
69 if (FT_New_Face(font.library, RESSOURCEPATH "fonts/Minecraftia.ttf", 0, &font.face)) {
70 fprintf(stderr, "Failed to load Minecraftia.ttf\n");
74 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
75 FT_Set_Pixel_Sizes(font.face, 0, 16);
77 for (unsigned char c = 0; c < NUM_CHARS; c++) {
78 if (FT_Load_Char(font.face, c, FT_LOAD_RENDER)) {
79 fprintf(stderr, "Failed to load glyph %c\n", c);
81 font.chars[c] = (Character) {
87 font.chars[c] = (Character) {
88 .texture = texture_create(font.face->glyph->bitmap.buffer, font.face->glyph->bitmap.width, font.face->glyph->bitmap.rows, GL_RED, false),
89 .bearing = {font.face->glyph->bitmap_left, font.face->glyph->bitmap_top},
90 .advance = font.face->glyph->advance.x,
95 font.height = font.chars['|'].texture->height;
97 FT_Done_Face(font.face);
98 FT_Done_FreeType(font.library);
105 for (unsigned char c = 0; c < NUM_CHARS; c++) {
106 if (font.chars[c].texture)
107 texture_delete(font.chars[c].texture);
111 Font *font_create(const char *text)
113 Font *fnt = malloc(sizeof(fnt));
115 size_t len = strlen(text);
117 fnt->meshes = malloc(sizeof(Mesh *) * len);
118 fnt->meshes_count = len;
120 GLfloat offset = 0.0f;
122 for (size_t i = 0; i < len; i++) {
123 unsigned char c = text[i];
125 if (c >= NUM_CHARS || ! font.chars[c].texture)
128 Character *ch = &font.chars[c];
130 GLfloat width = ch->texture->width;
131 GLfloat height = ch->texture->height;
133 GLfloat x = ch->bearing.x + offset;
134 GLfloat y = font.height - ch->bearing.y;
136 VertexFont vertices[6] = {
137 {{x, y }, {0.0f, 0.0f}},
138 {{x, y + height}, {0.0f, 1.0f}},
139 {{x + width, y + height}, {1.0f, 1.0f}},
140 {{x, y }, {0.0f, 0.0f}},
141 {{x + width, y + height}, {1.0f, 1.0f}},
142 {{x + width, y }, {1.0f, 0.0f}},
145 Mesh *mesh = fnt->meshes[i] = mesh_create();
146 mesh->textures = &ch->texture->id;
147 mesh->textures_count = 1;
148 mesh->free_textures = false;
149 mesh->vertices = vertices;
150 mesh->vertices_count = 6;
151 mesh->free_vertices = false;
152 mesh->layout = &vertex_layout;
153 mesh_configure(mesh);
155 offset += ch->advance >> 6;
158 fnt->size = (v2f32) {offset, font.height};
163 void font_delete(Font *fnt)
165 for (size_t i = 0; i < fnt->meshes_count; i++)
166 mesh_delete(fnt->meshes[i]);
171 void font_render(Font *fnt)
173 for (size_t i = 0; i < fnt->meshes_count; i++)
174 mesh_render(fnt->meshes[i]);