From 6b7fbf4fe476d908fd44ca9421363e053324ba69 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 24 Nov 2021 21:03:16 +0100 Subject: Fix glyphs overlapping, but adds unnecessary padding --- src/graphics/font.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/graphics/font.c b/src/graphics/font.c index 40fe641..fd1439d 100644 --- a/src/graphics/font.c +++ b/src/graphics/font.c @@ -5,12 +5,17 @@ #include "../../external/stb_truetype.h" /* TODO: Show a rectangle for unsupported glyphs or if |self| is NULL */ +/* TODO: Pack fonts tighter */ /* Need padding so filtering doesn't touch pixels in another glyphs area */ #define GLYPH_PADDING 2 #define GLYPH_UPSAMPLE 1 #define GLYPH_SHIFT 0.5f +static int round_float(float value) { + return value + 0.5f; +} + int mgl_font_load_from_file(mgl_font *self, const mgl_memory_mapped_file *mapped_file, unsigned int character_size) { self->texture.id = 0; @@ -23,7 +28,6 @@ int mgl_font_load_from_file(mgl_font *self, const mgl_memory_mapped_file *mapped self->character_size = character_size; mgl_font_char_map_init(&self->char_map); - self->current_line_max_height = 0; self->font_info = NULL; self->font_info = malloc(sizeof(stbtt_fontinfo)); @@ -47,7 +51,6 @@ void mgl_font_unload(mgl_font *self) { mgl_texture_unload(&self->texture); mgl_font_char_map_deinit(&self->char_map); - self->current_line_max_height = 0; free(self->font_info); self->font_info = NULL; @@ -61,9 +64,9 @@ static int align_up_to_next_value_of(int value, int alignment) { return value + (alignment - offset_to_next_alignment); } -static void mgl_font_handle_new_render_position(mgl_font *self, int glyph_width) { +static void mgl_font_handle_new_render_position(mgl_font *self, int glyph_width, int glyph_height) { if(self->font_atlas.pointer_position.x + glyph_width + GLYPH_PADDING >= self->font_atlas.width) { - if(self->font_atlas.pointer_position.y + self->current_line_max_height + GLYPH_PADDING >= self->font_atlas.height && self->font_atlas.render_section != MGL_ATLAS_SECTION_RIGHT) { + if(self->font_atlas.pointer_position.y + glyph_height + GLYPH_PADDING >= self->font_atlas.height && self->font_atlas.render_section != MGL_ATLAS_SECTION_RIGHT) { /* Texture atlas looks like this with glyphs filling the texture: |----| @@ -110,19 +113,18 @@ static void mgl_font_handle_new_render_position(mgl_font *self, int glyph_width) } else { fprintf(stderr, "Error: failed to resize font atlas\n"); } - } else if(self->font_atlas.render_section == MGL_ATLAS_SECTION_RIGHT && self->font_atlas.pointer_position.y + self->current_line_max_height + GLYPH_PADDING >= self->font_atlas.prev_height) { + } else if(self->font_atlas.render_section == MGL_ATLAS_SECTION_RIGHT && self->font_atlas.pointer_position.y + glyph_height + GLYPH_PADDING >= self->font_atlas.prev_height) { self->font_atlas.render_section = MGL_ATLAS_SECTION_BOTTOM; self->font_atlas.pointer_position.x = GLYPH_PADDING; - self->font_atlas.pointer_position.y += self->current_line_max_height + GLYPH_PADDING; + self->font_atlas.pointer_position.y += self->character_size + GLYPH_PADDING; } else { if(self->font_atlas.render_section != MGL_ATLAS_SECTION_RIGHT) { self->font_atlas.pointer_position.x = GLYPH_PADDING; } else { self->font_atlas.pointer_position.x = self->font_atlas.prev_width; } - self->font_atlas.pointer_position.y += self->current_line_max_height + GLYPH_PADDING; + self->font_atlas.pointer_position.y += self->character_size + GLYPH_PADDING; } - self->current_line_max_height = 0; } } @@ -196,7 +198,7 @@ int mgl_font_get_glyph(mgl_font *self, uint32_t codepoint, mgl_font_glyph *glyph if(existing_char_entry) { render_offset = existing_char_entry->render_offset; } else { - mgl_font_handle_new_render_position(self, width); + mgl_font_handle_new_render_position(self, width, height); render_offset.x = self->font_atlas.pointer_position.x; render_offset.y = self->font_atlas.pointer_position.y; @@ -205,7 +207,7 @@ int mgl_font_get_glyph(mgl_font *self, uint32_t codepoint, mgl_font_glyph *glyph new_glyph.size = (mgl_vec2i){ width/GLYPH_UPSAMPLE, height/GLYPH_UPSAMPLE }; new_glyph.texture_position = (mgl_vec2i){ render_offset.x, render_offset.y }; new_glyph.texture_size = (mgl_vec2i){ width, height }; - new_glyph.advance = glyph_advance/GLYPH_UPSAMPLE; + new_glyph.advance = round_float(glyph_advance/GLYPH_UPSAMPLE); *glyph = new_glyph; if(mgl_font_char_map_insert(&self->char_map, codepoint, &new_glyph, &existing_char_entry) != 0) { @@ -215,9 +217,6 @@ int mgl_font_get_glyph(mgl_font *self, uint32_t codepoint, mgl_font_glyph *glyph } existing_char_entry->render_offset = render_offset; - if(height > self->current_line_max_height) - self->current_line_max_height = height; - self->font_atlas.pointer_position.x += width + GLYPH_PADDING; } @@ -239,5 +238,5 @@ int mgl_font_get_glyph(mgl_font *self, uint32_t codepoint, mgl_font_glyph *glyph float mgl_font_get_kerning(const mgl_font *self, uint32_t prev_codepoint, uint32_t codepoint) { if(!self || self->texture.id == 0) return 0.0f; - return stbtt_GetCodepointKernAdvance(self->font_info, prev_codepoint, codepoint) * stbtt_ScaleForPixelHeight(self->font_info, self->character_size); + return round_float(stbtt_GetCodepointKernAdvance(self->font_info, prev_codepoint, codepoint) * stbtt_ScaleForPixelHeight(self->font_info, self->character_size)); } -- cgit v1.2.3