aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mgl/graphics/font.h3
-rw-r--r--include/mgl/graphics/text.h3
-rw-r--r--src/graphics/font.c26
-rw-r--r--src/graphics/text.c25
4 files changed, 32 insertions, 25 deletions
diff --git a/include/mgl/graphics/font.h b/include/mgl/graphics/font.h
index 4bd0428..118a867 100644
--- a/include/mgl/graphics/font.h
+++ b/include/mgl/graphics/font.h
@@ -25,7 +25,8 @@ typedef struct {
} mgl_font_atlas;
struct mgl_font {
- mgl_texture texture; /* Font texture coordinates are in pixel space */
+ /* Font texture coordinates are in pixel space. Note: the texture id may change */
+ mgl_texture texture;
mgl_font_atlas font_atlas;
unsigned int character_size;
mgl_font_char_map char_map;
diff --git a/include/mgl/graphics/text.h b/include/mgl/graphics/text.h
index 08a6c37..89ae541 100644
--- a/include/mgl/graphics/text.h
+++ b/include/mgl/graphics/text.h
@@ -22,6 +22,7 @@ typedef struct {
mgl_color color;
mgl_vec2f position;
mgl_vec2f bounds;
+ bool bounds_dirty;
} mgl_text;
/*
@@ -40,7 +41,7 @@ void mgl_text_set_string(mgl_text *self, const char *str, size_t str_size);
void mgl_text_set_font(mgl_text *self, mgl_font *font);
void mgl_text_set_position(mgl_text *self, mgl_vec2f position);
void mgl_text_set_color(mgl_text *self, mgl_color color);
-mgl_vec2f mgl_text_get_bounds(const mgl_text *self);
+mgl_vec2f mgl_text_get_bounds(mgl_text *self);
/* Returns the position of the character on the screen (relative to the current mgl_view) */
mgl_vec2f mgl_text_find_character_pos(mgl_text *self, size_t index);
void mgl_text_draw(mgl_context *context, mgl_text *text);
diff --git a/src/graphics/font.c b/src/graphics/font.c
index 17362f6..aa349a6 100644
--- a/src/graphics/font.c
+++ b/src/graphics/font.c
@@ -4,8 +4,8 @@
#define STB_TRUETYPE_IMPLEMENTATION
#include "../../external/stb_truetype.h"
-/* Need padding so filtering doesn't touch pixels in another glyphs area. TODO: Decrease this */
-#define GLYPH_PADDING 4
+/* Need padding so filtering doesn't touch pixels in another glyphs area */
+#define GLYPH_PADDING 2
#define GLYPH_UPSAMPLE 1
int mgl_font_load_from_file(mgl_font *self, const mgl_memory_mapped_file *mapped_file, unsigned int character_size) {
@@ -36,11 +36,6 @@ int mgl_font_load_from_file(mgl_font *self, const mgl_memory_mapped_file *mapped
return -1;
}
- if(mgl_texture_init(&self->texture) != 0) {
- mgl_font_unload(self);
- return -1;
- }
-
/* TODO: Use stbtt_GetCodepointSDF */
return 0;
}
@@ -130,12 +125,16 @@ 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) {
+ if(self->texture.id == 0 && mgl_texture_init(&self->texture) != 0)
+ return -1;
+
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,
.pixel_coordinates = true
};
+
if(mgl_texture_load_from_memory(&self->texture, NULL, initial_atlas_size, initial_atlas_size, MGL_IMAGE_FORMAT_ALPHA, &load_options) == 0) {
/*fprintf(stderr, "Error: failed to create font atlas texture, error: mgl_texture_load_from_memory failed\n");*/
self->font_atlas.width = initial_atlas_size;
@@ -176,12 +175,13 @@ int mgl_font_get_glyph(mgl_font *self, uint32_t codepoint, mgl_font_glyph *glyph
int yoff = y0;
/* TODO: Use stbtt_MakeGlyphBitmapSubpixelPrefilter instead for better text quality */
- const size_t pixels_size = (width + GLYPH_PADDING * 2) * (height + GLYPH_PADDING * 2);
- unsigned char *pixels = malloc(pixels_size);
+ const size_t pixels_width = (width + GLYPH_PADDING * 2);
+ const size_t pixels_height = (height + GLYPH_PADDING * 2);
+ const size_t pixels_size = pixels_width * pixels_height;
+ unsigned char *pixels = calloc(pixels_size, 1);
if(pixels) {
- /* TODO: Is this needed? */
- /*memset(pixels, 0, pixels_size);*/
- stbtt_MakeGlyphBitmapSubpixel(self->font_info, pixels, width, height, width, font_scale, font_scale, GLYPH_PADDING, GLYPH_PADDING, glyph_index);
+ const int top_padding = GLYPH_PADDING;
+ stbtt_MakeGlyphBitmap(self->font_info, pixels + pixels_width * top_padding + GLYPH_PADDING, width, height, pixels_width, font_scale, font_scale, glyph_index);
}
mgl_vec2i render_offset;
@@ -223,7 +223,7 @@ int mgl_font_get_glyph(mgl_font *self, uint32_t codepoint, mgl_font_glyph *glyph
}
}
- const int res = mgl_texture_update(&self->texture, pixels, render_offset.x, render_offset.y, width, height, MGL_IMAGE_FORMAT_ALPHA);
+ const int res = mgl_texture_update(&self->texture, pixels, render_offset.x - GLYPH_PADDING, render_offset.y - GLYPH_PADDING, pixels_width, pixels_height, MGL_IMAGE_FORMAT_ALPHA);
free(pixels);
return res;
}
diff --git a/src/graphics/text.c b/src/graphics/text.c
index 3620659..66ef7e3 100644
--- a/src/graphics/text.c
+++ b/src/graphics/text.c
@@ -90,6 +90,7 @@ void mgl_text_init(mgl_text *self, mgl_font *font, const char *str, size_t str_s
self->position = (mgl_vec2f){ 0.0f, 0.0f };
self->text = NULL;
self->text_size = 0;
+ self->bounds_dirty = true;
mgl_text_set_string(self, str, str_size);
}
@@ -105,19 +106,13 @@ void mgl_text_set_string(mgl_text *self, const char *str, size_t str_size) {
self->text = str;
self->text_size = str_size;
if(self->text && self->text_size > 0 && self->font)
- self->bounds = mgl_text_calculate_bounds(self);
- else
- self->bounds = (mgl_vec2f){ 0.0f, 0.0f };
+ self->bounds_dirty = true;
}
void mgl_text_set_font(mgl_text *self, mgl_font *font) {
self->font = font;
- if(self->font) {
- if(self->bounds.x < 0.001f && self->bounds.y < 0.001f && self->text && self->text_size > 0)
- self->bounds = mgl_text_calculate_bounds(self);
- } else {
- self->bounds = (mgl_vec2f){ 0.0f, 0.0f };
- }
+ if(self->text && self->text_size > 0 && self->font)
+ self->bounds_dirty = true;
}
void mgl_text_set_position(mgl_text *self, mgl_vec2f position) {
@@ -128,7 +123,14 @@ void mgl_text_set_color(mgl_text *self, mgl_color color) {
self->color = color;
}
-mgl_vec2f mgl_text_get_bounds(const mgl_text *self) {
+mgl_vec2f mgl_text_get_bounds(mgl_text *self) {
+ if(self->bounds_dirty) {
+ self->bounds_dirty = false;
+ if(self->text && self->text_size > 0 && self->font)
+ self->bounds = mgl_text_calculate_bounds(self);
+ else
+ self->bounds = (mgl_vec2f){ 0.0f, 0.0f };
+ }
return self->bounds;
}
@@ -210,6 +212,9 @@ void mgl_text_draw(mgl_context *context, mgl_text *text) {
if(!text->text || text->text_size == 0 || !text->font)
return;
+ /* Calculate bounds beforehand if needed, which also generates glyphs because opengl outputs an error if that is done inside glBegin/glEnd */
+ mgl_text_get_bounds(text);
+
TextDrawUserdata text_draw_userdata;
text_draw_userdata.position = (mgl_vec2f){ text->position.x, text->position.y + text->font->character_size };
text_draw_userdata.text = text;