aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mgl/graphics/font.h1
-rw-r--r--src/graphics/font.c27
-rw-r--r--tests/main.c22
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)