diff options
| -rw-r--r-- | font.c | 64 | ||||
| -rw-r--r-- | font.h | 2 | ||||
| -rw-r--r-- | main.c | 4 | ||||
| -rw-r--r-- | seat.c | 2 | ||||
| -rw-r--r-- | state.h | 16 |
5 files changed, 85 insertions, 3 deletions
@@ -59,6 +59,70 @@ bool init_freetype(client_state* state, const char* file) { fprintf(stderr, "Failed to set font size\n"); return false; } + return true; +} + +bool init_atlas(client_state* state) { + FT_Int32 load_flags = FT_LOAD_RENDER | FT_LOAD_TARGET_(FT_RENDER_MODE_SDF); + for (int i = 32; i < 128; i++) { + if (FT_Load_Char(state->ft_face, i, load_flags)) { + fprintf(stderr, "Failed to render character %c\n", (char)i); + } + printf("%c: %u, %u\n", (char)i, state->ft_face->glyph->bitmap.width, state->ft_face->glyph->bitmap.rows); + state->atlas.width += state->ft_face->glyph->bitmap.width; + state->atlas.height = MAX(state->atlas.height, state->ft_face->glyph->bitmap.rows); + } + + glActiveTexture(GL_TEXTURE0); + glGenTextures(1, &state->atlas.texture); + glBindTexture(GL_TEXTURE_2D, state->atlas.texture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RED, + (GLsizei) state->atlas.width, + (GLsizei) state->atlas.height, + 0, + GL_RED, + GL_UNSIGNED_BYTE, + NULL); + + uint32_t x = 0; + for (int i = 32; i < 128; i++) { + if (FT_Load_Char(state->ft_face, i, load_flags)) { + fprintf(stderr, "Failed to render character %c\n", (char)i); + } + + if (FT_Render_Glyph(state->ft_face->glyph, FT_RENDER_MODE_NORMAL)) { + fprintf(stderr, "ERROR: could not render glyph of a character with code %d\n", i); + } + + state->atlas.metrics[i].advance_x = (float)state->ft_face->glyph->advance.x / 64; + state->atlas.metrics[i].advance_y = (float)state->ft_face->glyph->advance.y / 64; + state->atlas.metrics[i].bitmap_width = state->ft_face->glyph->bitmap.width; + state->atlas.metrics[i].bitmap_height = state->ft_face->glyph->bitmap.rows; + state->atlas.metrics[i].texture_offset = x; + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexSubImage2D( + GL_TEXTURE_2D, + 0, + x, + 0, + state->ft_face->glyph->bitmap.width, + state->ft_face->glyph->bitmap.rows, + GL_RED, + GL_UNSIGNED_BYTE, + state->ft_face->glyph->bitmap.buffer); + x += state->ft_face->glyph->bitmap.width; + } return true; } @@ -2,7 +2,9 @@ #define FONT_H_ #include "state.h" + char* get_font(const char* font_name); bool init_freetype(client_state* state, const char* font); +bool init_atlas(client_state* state); #endif // FONT_H_ @@ -36,12 +36,14 @@ int main() { } char* font = get_font("Monospace"); - printf("font: %s\n", font); if (!init_freetype(&state, font)) { fprintf(stderr, "Failed to Initalize FreeType\n"); } free(font); + init_atlas(&state); + + // event loop while (state.running) { poll_events(&state); @@ -12,8 +12,6 @@ void setup_seat(client_state* state) { void capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities) { client_state* state = data; - - printf("seat capablities\n"); if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD && !state->keyboard) { setup_keyboard(state); } @@ -16,6 +16,20 @@ #include "./glad/glad.h" +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + +typedef struct { + float advance_x, advance_y; + uint32_t bitmap_width, bitmap_height; + uint32_t texture_offset; +} metrics_t; + +typedef struct { + uint32_t width, height; + GLuint texture; + metrics_t metrics[128]; +} atlas_t; + typedef struct { // wayland struct wl_display* display; @@ -53,6 +67,8 @@ typedef struct { FT_Library ft_library; FT_Face ft_face; + atlas_t atlas; + bool running; } client_state; |
