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