diff options
Diffstat (limited to 'src/mgui/richtext.c')
-rw-r--r-- | src/mgui/richtext.c | 58 |
1 files changed, 42 insertions, 16 deletions
diff --git a/src/mgui/richtext.c b/src/mgui/richtext.c index c70967f..9b1acfc 100644 --- a/src/mgui/richtext.c +++ b/src/mgui/richtext.c @@ -28,6 +28,10 @@ static int max_int(int a, int b) { return a >= b ? a : b; } +static int min_int(int a, int b) { + return a <= b ? a : b; +} + /* TODO: Is there a more efficient way to do this? maybe japanese characters have a specific bit-pattern? */ static bool is_japanese_codepoint(uint32_t codepoint) { return (codepoint >= 0x2E80 && codepoint <= 0x2FD5) /* Kanji radicals */ @@ -93,6 +97,13 @@ static void mgui_richtext_vertices_clear(mgui_richtext *self, size_t vertex_inde self->vertex_data[vertex_index].vertex_count = 0; } +static void mgui_richtext_vertices_free(mgui_richtext *self, size_t vertex_index) { + mgui_free(self->vertex_data[vertex_index].vertices); + self->vertex_data[vertex_index].vertices = NULL; + self->vertex_data[vertex_index].vertices_capacity = 0; + self->vertex_data[vertex_index].vertex_count = 0; +} + mgui_richtext* mgui_richtext_create(const char *str, size_t size, unsigned char character_size) { mgui_richtext *richtext = mgui_alloc(sizeof(mgui_richtext)); mgui_widget_init(&richtext->widget, MGUI_WIDGET_RICHTEXT); @@ -133,17 +144,6 @@ void mgui_richtext_set_position(mgui_richtext *self, mgl_vec2i position) { self->position = position; } -void mgui_richtext_set_width(mgui_richtext *self, int width) { - self->width = width; -} - -void mgui_richtext_on_event(mgui_richtext *self, mgl_window *window, mgl_event *event) { - /* TODO: Implement */ - (void)self; - (void)window; - (void)event; -} - static void mgui_richtext_append_glyph(mgui_richtext *self, size_t vertex_index, mgl_vec2f position, mgl_color color, mgl_font_glyph *glyph) { const mgl_vertex top_left_vertex = { .position = (mgl_vec2f){ round_float(position.x + glyph->position.x), round_float(position.y + glyph->position.y) }, @@ -229,8 +229,8 @@ static void mgui_richtext_update(mgui_richtext *self) { } else { if(mgl_font_get_glyph(font, codepoint, &glyph) == 0) { if(position.x + glyph.size.x > self->width) { - //position.x = 0; - //position.y += self->character_size; + position.x = 0; + position.y += self->character_size; } mgui_richtext_append_glyph(self, vertex_index, position, color, &glyph); @@ -245,14 +245,37 @@ static void mgui_richtext_update(mgui_richtext *self) { } } -mgl_vec2i mgui_richtext_draw(mgui_richtext *self, mgl_window *window) { +void mgui_richtext_calculate_size(mgui_richtext *self, mgl_vec2i max_size) { /* TODO: Do not update if not visible on screen? */ + if(max_size.x != self->width) { + self->width = max_size.x; + self->dirty = true; + } + + /* TODO: Instead of updating richtext vertices, calculcate the richtext bounds only and update the vertices in the draw function if dirty */ if(self->dirty) { self->dirty = false; mgui_richtext_update(self); + self->widget.size.x = self->render_size.x; + self->widget.size.y = min_int(self->render_size.y, max_size.y); } +} + +void mgui_richtext_on_event(mgui_richtext *self, mgl_window *window, mgl_event *event) { + /* TODO: Implement */ + (void)self; + (void)window; + (void)event; +} +void mgui_richtext_draw(mgui_richtext *self, mgl_window *window) { if(mgui_rectangle_intersects_with_scissor(self->position, self->render_size, window)) { + /* This can happen when the item is first not visible in its scissor and then becomes visible */ + if(self->dirty) { + self->dirty = false; + mgui_richtext_update(self); + } + const mgui_font_type font_types[NUM_VERTEX_DATA] = { MGUI_FONT_LATIN, MGUI_FONT_CJK @@ -268,7 +291,10 @@ mgl_vec2i mgui_richtext_draw(mgui_richtext *self, mgl_window *window) { } mgl_texture_use(NULL); + } else { + for(size_t i = 0; i < NUM_VERTEX_DATA; ++i) { + mgui_richtext_vertices_free(self, i); + } + self->dirty = true; } - - return self->render_size; } |