aboutsummaryrefslogtreecommitdiff
path: root/src/graphics/text.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphics/text.c')
-rw-r--r--src/graphics/text.c55
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;
}