diff options
-rw-r--r-- | include/mgl/graphics/font.h | 1 | ||||
-rw-r--r-- | src/graphics/font.c | 27 | ||||
-rw-r--r-- | tests/main.c | 22 |
3 files changed, 24 insertions, 26 deletions
diff --git a/include/mgl/graphics/font.h b/include/mgl/graphics/font.h index 118a867..6b10feb 100644 --- a/include/mgl/graphics/font.h +++ b/include/mgl/graphics/font.h @@ -30,7 +30,6 @@ struct mgl_font { mgl_font_atlas font_atlas; unsigned int character_size; mgl_font_char_map char_map; - int current_line_max_height; void *font_info; }; 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)); } diff --git a/tests/main.c b/tests/main.c index b341bb3..0d4f096 100644 --- a/tests/main.c +++ b/tests/main.c @@ -56,8 +56,8 @@ static void draw(mgl_window *window, void *userdata) { u->fps_counter = 0; fprintf(stderr, "fps: %d\n", u->fps); } - char str[255]; - snprintf(str, sizeof(str), "hello|fps\nåäö: %d", u->fps); + char str[512]; + snprintf(str, sizeof(str), ",.-_/1234567890½!\"#¤%%&/()=?¡@£$€¥{[]}\\'abcdefghijklmnopqrstuvwxyzáàäåãâíìîïúùũüûéèẽëêóòõôöABCDEFGHIJKLMNOPQRSTUVWXYZÁÀÄÅÃÂÍÌÎÏÚÙŨÜÛÉÈẼËÊÓÒÕÔÖ └> pacman -Q quickmedia-git"); mgl_text text; mgl_text_init(&text, u->font, str, strlen(str)); @@ -120,7 +120,7 @@ static void draw(mgl_window *window, void *userdata) { mgl_rectangle rect = { .position = { window->cursor_position.x, window->cursor_position.y }, - .size = { u->cjk_font->texture.width, u->cjk_font->texture.height }, + .size = { u->font->texture.width, u->font->texture.height }, .color = { 255, 255, 255, 255 }, }; mgl_rectangle_draw(context, &rect); @@ -132,25 +132,25 @@ static void draw(mgl_window *window, void *userdata) { .color = {255, 0, 0, 100} }, (mgl_vertex){ - .position = {u->cjk_font->texture.width, 0.0f}, - .texcoords = {u->cjk_font->texture.width, 0.0f}, + .position = {u->font->texture.width, 0.0f}, + .texcoords = {u->font->texture.width, 0.0f}, .color = {0, 255, 0, 100}, }, (mgl_vertex){ - .position = {u->cjk_font->texture.width, u->cjk_font->texture.height}, - .texcoords = {u->cjk_font->texture.width, u->cjk_font->texture.height}, + .position = {u->font->texture.width, u->font->texture.height}, + .texcoords = {u->font->texture.width, u->font->texture.height}, .color = {0, 0, 255, 100}, }, (mgl_vertex){ - .position = {0.0f, u->cjk_font->texture.height}, - .texcoords = {0.0f, u->cjk_font->texture.height}, + .position = {0.0f, u->font->texture.height}, + .texcoords = {0.0f, u->font->texture.height}, .color = {255, 0, 255, 100} } }; mgl_vertex_buffer_update(u->vertex_buffer1, vertices1, 4, MGL_PRIMITIVE_QUADS, MGL_USAGE_STREAM); mgl_vertex_buffer_set_position(u->vertex_buffer1, (mgl_vec2f){ window->cursor_position.x, window->cursor_position.y }); - mgl_vertex_buffer_draw(context, u->vertex_buffer1, &u->cjk_font->texture); + mgl_vertex_buffer_draw(context, u->vertex_buffer1, &u->font->texture); } static void test_hash_map_get_insert(mgl_font_char_map *char_map, uint32_t unicode, bool exists) { @@ -250,7 +250,7 @@ int main(int argc, char **argv) { if(mgl_texture_load_from_file(&texture, "tests/X11.jpg", &(mgl_texture_load_options){ false, false }) != 0) return 1; - if(mgl_mapped_file_load("/usr/share/fonts/noto/NotoSans-Regular.ttf", &font_file, &(mgl_memory_mapped_file_load_options){ .readable = true, .writable = false }) != 0) + if(mgl_mapped_file_load("/usr/share/fonts/TTF/Hack-Regular.ttf", &font_file, &(mgl_memory_mapped_file_load_options){ .readable = true, .writable = false }) != 0) return 1; if(mgl_mapped_file_load("/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc", &cjk_font_file, &(mgl_memory_mapped_file_load_options){ .readable = true, .writable = false }) != 0) |