diff options
| author | Riley Beckett <rbeckettvt@gmail.com> | 2025-10-12 19:19:03 -0400 |
|---|---|---|
| committer | Riley Beckett <rbeckettvt@gmail.com> | 2025-10-12 19:19:03 -0400 |
| commit | 458f9d0b5f1b83d3f2e11cead790cdf6ac867e11 (patch) | |
| tree | ae3dd115a00695eec838d62a4181b2753dbb89b0 | |
| parent | d71f3c26c26c22ac6782944f5732274abe64f8f8 (diff) | |
get width of string
| -rw-r--r-- | font.c | 38 | ||||
| -rw-r--r-- | font.h | 7 | ||||
| -rw-r--r-- | graphics.c | 13 | ||||
| -rw-r--r-- | main.c | 17 | ||||
| -rw-r--r-- | state.h | 7 |
5 files changed, 53 insertions, 29 deletions
@@ -46,7 +46,7 @@ char* get_font(const char* font_name) { return font; } -bool init_freetype(client_state* state, const char* file) { +bool freetype_init(client_state* state, const char* file) { if (FT_Init_FreeType(&state->ft_library)) { fprintf(stderr, "Failed to intalize FreeType Library\n"); return false; @@ -59,20 +59,27 @@ bool init_freetype(client_state* state, const char* file) { fprintf(stderr, "Failed to set font size\n"); return false; } + state->load_flags = FT_LOAD_RENDER | FT_LOAD_TARGET_(FT_RENDER_MODE_SDF); return true; } -bool init_atlas(client_state* state) { - FT_Int32 load_flags = FT_LOAD_RENDER | FT_LOAD_TARGET_(FT_RENDER_MODE_SDF); +void atlas_init(client_state* state) { for (int i = 32; i < 128; i++) { - if (FT_Load_Char(state->ft_face, i, load_flags)) { + if (FT_Load_Char(state->ft_face, i, state->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); + + metric_t* metric = &state->atlas.metrics[i]; + metric->advance_x = (float)state->ft_face->glyph->advance.x / 64; + metric->advance_y = (float)state->ft_face->glyph->advance.y / 64; + metric->bitmap_width = state->ft_face->glyph->bitmap.width; + metric->bitmap_height = state->ft_face->glyph->bitmap.rows; } +} +void atlas_create_texture(client_state* state) { glActiveTexture(GL_TEXTURE0); glGenTextures(1, &state->atlas.texture); glBindTexture(GL_TEXTURE_2D, state->atlas.texture); @@ -96,19 +103,12 @@ bool init_atlas(client_state* state) { uint32_t x = 0; for (int i = 32; i < 128; i++) { - if (FT_Load_Char(state->ft_face, i, load_flags)) { + if (FT_Load_Char(state->ft_face, i, state->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; + metric_t* metric = &state->atlas.metrics[i]; + metric->texture_offset = (float)x / state->atlas.width; glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexSubImage2D( @@ -123,6 +123,12 @@ bool init_atlas(client_state* state) { state->ft_face->glyph->bitmap.buffer); x += state->ft_face->glyph->bitmap.width; } +} - return true; +int atlas_get_strwidth(client_state* state, const char* str) { + float width = 0; + for (int i = 0; i < strlen(str); i++) { + width += ceil(state->atlas.metrics[(int)str[i]].advance_x); + } + return (int)ceil(width); } @@ -4,7 +4,10 @@ char* get_font(const char* font_name); -bool init_freetype(client_state* state, const char* font); -bool init_atlas(client_state* state); +bool freetype_init(client_state* state, const char* font); +void atlas_init(client_state* state); +void atlas_create_texture(client_state* state); + +int atlas_get_strwidth(client_state* state, const char* str); #endif // FONT_H_ @@ -75,5 +75,18 @@ bool init_gl(client_state* state) { void render_frame(client_state *state) { glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, state->atlas.texture); + + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(-1,1); + glTexCoord2f(0, 1); glVertex2f(-1,-1); + glTexCoord2f(1, 1); glVertex2f(1,-1); + glTexCoord2f(1, 0); glVertex2f(1,1); + glEnd(); + + glDisable(GL_TEXTURE_2D); + eglSwapBuffers(state->egl_display, state->egl_surface); } @@ -14,6 +14,14 @@ int main() { client_state state = {0}; state.running = true; + char* font = get_font("Monospace"); + if (!freetype_init(&state, font)) { + fprintf(stderr, "Failed to Initalize FreeType\n"); + } + free(font); + + atlas_init(&state); + state.display = wl_display_connect(NULL); if (!state.display) { fprintf(stderr, "Failed to Connect to wayland display\n"); @@ -35,14 +43,7 @@ int main() { return 1; } - char* font = get_font("Monospace"); - if (!init_freetype(&state, font)) { - fprintf(stderr, "Failed to Initalize FreeType\n"); - } - free(font); - - init_atlas(&state); - + atlas_create_texture(&state); // event loop while (state.running) { @@ -21,13 +21,13 @@ typedef struct { float advance_x, advance_y; uint32_t bitmap_width, bitmap_height; - uint32_t texture_offset; -} metrics_t; + float texture_offset; +} metric_t; typedef struct { uint32_t width, height; GLuint texture; - metrics_t metrics[128]; + metric_t metrics[128]; } atlas_t; typedef struct { @@ -66,6 +66,7 @@ typedef struct { FT_Library ft_library; FT_Face ft_face; + FT_Int32 load_flags; atlas_t atlas; |
