diff options
Diffstat (limited to 'src/graphics/text.c')
-rw-r--r-- | src/graphics/text.c | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/src/graphics/text.c b/src/graphics/text.c index 723b37a..31ae794 100644 --- a/src/graphics/text.c +++ b/src/graphics/text.c @@ -11,6 +11,8 @@ takes a while. */ +#define TAB_WIDTH 4 + static bool default_syntax_highlight(void *userdata, const char *str, size_t size, mgl_color *color) { (void)userdata; (void)str; @@ -19,10 +21,42 @@ static bool default_syntax_highlight(void *userdata, const char *str, size_t siz return false; } +static float fmax(float a, float b) { + return a >= b ? a : b; +} + +static mgl_vec2f mgl_text_calculate_bounds(mgl_text *self) { + mgl_vec2f bounds; + bounds.x = 0.0f; + bounds.y = self->font->character_size; + + /* TODO: Combine this with the loop in mgl_text_draw */ + mgl_font_glyph glyph; + float width = 0.0f; + for(size_t i = 0; i < self->text_size; ++i) { + unsigned char c = *(unsigned char*)&self->text[i]; + if((c >= 32 && c < 128)) { + if(mgl_font_get_glyph(self->font, c, &glyph) == 0) { + width += glyph.advance; + bounds.x = fmax(bounds.x, width); + } + } else if(c == '\t') { + if(mgl_font_get_glyph(self->font, ' ', &glyph) == 0) { + width += (glyph.advance * TAB_WIDTH); + bounds.x = fmax(bounds.x, width); + } + } else if(c == '\n') { + width = 0.0f; + bounds.y += self->font->character_size; + } + } + + return bounds; +} + int mgl_text_init(mgl_text *self, mgl_font *font, const char *str, size_t str_size, mgl_text_options *options) { self->font = font; - self->text = str; - self->text_size = str_size; + mgl_text_set_string(self, str, str_size); self->color = (mgl_color){ 255, 255, 255, 255 }; self->position = (mgl_vec2f){ 0.0f, 0.0f }; @@ -46,10 +80,20 @@ void mgl_text_deinit(mgl_text *self) { 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 }; } 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->bounds = mgl_text_calculate_bounds(self); + } else { + self->bounds = (mgl_vec2f){ 0.0f, 0.0f }; + } } void mgl_text_set_position(mgl_text *self, mgl_vec2f position) { @@ -60,6 +104,10 @@ void mgl_text_set_color(mgl_text *self, mgl_color color) { self->color = color; } +mgl_vec2f mgl_text_get_bounds(const mgl_text *self) { + return self->bounds; +} + static void mgl_text_draw_glyph(mgl_context *context, mgl_font_glyph *glyph, mgl_vec2f position) { context->gl.glTexCoord2f(glyph->texture_position.x, glyph->texture_position.y); context->gl.glVertex3f(position.x + glyph->position.x, position.y + glyph->position.y, 0.0f); @@ -116,8 +164,7 @@ void mgl_text_draw(mgl_context *context, mgl_text *text) { } } else if(c == '\t') { if(mgl_font_get_glyph(text->font, ' ', &glyph) == 0) { - const int tab_width = 4; - for(int i = 0; i < tab_width; ++i) { + for(int i = 0; i < TAB_WIDTH; ++i) { mgl_text_draw_glyph(context, &glyph, position); position.x += glyph.advance; } |