aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-11-17 03:15:16 +0100
committerdec05eba <dec05eba@protonmail.com>2021-11-17 03:15:16 +0100
commitc18f87ad13da518af5ff245dbce2a9e608097ea1 (patch)
tree3ca8a22df68fc1ef7ecd7b9ec449a733b76de67a /src
parentccd0e65a0ddccd9c52d4c075ec1cad41ae7edb40 (diff)
Attempt to fix font glyph texture overlap by aligning texture size to
next character size Add function to get the start of a utf8 codepoint (backwards), test utf8 functions
Diffstat (limited to 'src')
-rw-r--r--src/graphics/font.c19
-rw-r--r--src/graphics/font_char_map.c1
-rw-r--r--src/system/utf8.c17
3 files changed, 31 insertions, 6 deletions
diff --git a/src/graphics/font.c b/src/graphics/font.c
index 0044d96..f73c023 100644
--- a/src/graphics/font.c
+++ b/src/graphics/font.c
@@ -4,8 +4,6 @@
#define STB_TRUETYPE_IMPLEMENTATION
#include "../../external/stb_truetype.h"
-/* TODO: Use correct atlas padding after resize. Its incorrect because padding from previous size doesn't accumulate */
-
/* Need padding so filtering doesn't touch pixels in another glyphs area */
#define GLYPH_PADDING 2
#define GLYPH_UPSAMPLE 1
@@ -57,6 +55,14 @@ void mgl_font_unload(mgl_font *self) {
self->font_info = NULL;
}
+static int align_up_to_next_value_of(int value, int alignment) {
+ int offset_to_next_alignment = value % alignment;
+ if(offset_to_next_alignment == 0)
+ return value;
+ else
+ return value + (alignment - offset_to_next_alignment);
+}
+
static void mgl_font_handle_new_render_position(mgl_font *self, int glyph_width) {
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) {
@@ -87,8 +93,8 @@ static void mgl_font_handle_new_render_position(mgl_font *self, int glyph_width)
if(mgl_texture_resize(&self->texture, self->font_atlas.width * 2, self->font_atlas.height * 2, NULL) == 0) {
self->font_atlas.prev_width = self->font_atlas.width;
self->font_atlas.prev_height = self->font_atlas.height;
- self->font_atlas.width *= 2;
- self->font_atlas.height *= 2;
+ self->font_atlas.width = align_up_to_next_value_of(self->font_atlas.width * 2, self->character_size);
+ self->font_atlas.height = align_up_to_next_value_of(self->font_atlas.height * 2, self->character_size);
self->font_atlas.render_section = MGL_ATLAS_SECTION_RIGHT;
self->font_atlas.pointer_position.x = self->font_atlas.prev_width;
@@ -99,6 +105,7 @@ static void mgl_font_handle_new_render_position(mgl_font *self, int glyph_width)
mgl_font_glyph glyph_dummy;
mgl_font_char_iterator font_char_it = mgl_font_char_map_begin(&self->char_map);
while(font_char_it.value) {
+ /* TODO: Update glyph without calling this, since this needs to get glyph from hash map again */
mgl_font_get_glyph(self, font_char_it.value->key, &glyph_dummy);
mgl_font_char_iterator_next(&font_char_it);
}
@@ -108,7 +115,7 @@ static void mgl_font_handle_new_render_position(mgl_font *self, int glyph_width)
} 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) {
self->font_atlas.render_section = MGL_ATLAS_SECTION_BOTTOM;
self->font_atlas.pointer_position.x = GLYPH_PADDING;
- self->font_atlas.pointer_position.y = self->font_atlas.prev_height;
+ self->font_atlas.pointer_position.y += self->current_line_max_height + GLYPH_PADDING;
} else {
if(self->font_atlas.render_section != MGL_ATLAS_SECTION_RIGHT) {
self->font_atlas.pointer_position.x = GLYPH_PADDING;
@@ -123,7 +130,7 @@ static void mgl_font_handle_new_render_position(mgl_font *self, int glyph_width)
int mgl_font_get_glyph(mgl_font *self, uint32_t codepoint, mgl_font_glyph *glyph) {
if(self->font_atlas.width == 0) {
- const int initial_atlas_size = 128;
+ const int initial_atlas_size = align_up_to_next_value_of(128, self->character_size);
/* TODO: Scale by character size */
mgl_texture_load_options load_options = {
.compressed = false,
diff --git a/src/graphics/font_char_map.c b/src/graphics/font_char_map.c
index abaa56a..64c4674 100644
--- a/src/graphics/font_char_map.c
+++ b/src/graphics/font_char_map.c
@@ -12,6 +12,7 @@
#error Unsupported system. Only systems where a pointer is 32-bits or 64-bits are supported.
#endif
+/* |align| should be a multiple of 2 */
static size_t align_to(size_t value, size_t align) {
const size_t is_aligned = (value & (align - 1));
if(is_aligned == 0) {
diff --git a/src/system/utf8.c b/src/system/utf8.c
index 201fedf..5d5ec79 100644
--- a/src/system/utf8.c
+++ b/src/system/utf8.c
@@ -73,3 +73,20 @@ bool mgl_utf8_decode(const unsigned char *str, size_t size, uint32_t *decoded_co
*decoded_codepoint = codepoint;
return true;
}
+
+/* TODO: Optimize (remove branching, etc) */
+size_t mgl_utf8_get_start_of_codepoint(const unsigned char *str, size_t size, size_t offset) {
+ if(size == 0)
+ return 0;
+
+ if(offset > size - 1)
+ offset = size - 1;
+
+ /* i <= offset is an overflow (underflow?) check */
+ for(size_t i = offset; i <= offset; --i) {
+ if((str[i] & 0xC0) != 0x80)
+ return i;
+ }
+
+ return 0;
+}