commit 0e40d68a8b98ca331bfad96d3293d9c01c5875ca
parent 440540f9caf405888a176c460cffff8669478b9e
Author: lumidify <nobody@lumidify.org>
Date:   Fri, 15 May 2020 09:39:58 +0200
Fix errors with resizing arrays; test inserting text
Diffstat:
8 files changed, 53 insertions(+), 37 deletions(-)
diff --git a/array.h b/array.h
@@ -82,16 +82,17 @@ ltk_array_prepare_gap_##name(struct ltk_array_##name *ar, size_t index, size_t l
 	}										\
 	ltk_array_resize_##name(ar, ar->len + len);					\
 	ar->len += len;									\
-	if (ar->len == index)								\
+	if (ar->len - len == index)							\
 		return;									\
-	memmove(ar->buf + index + len, ar->buf + index, ar->len - index);		\
+	memmove(ar->buf + index + len, ar->buf + index,					\
+	    (ar->len - len - index) * sizeof(type));					\
 }											\
 											\
 void											\
 ltk_array_insert_##name(struct ltk_array_##name *ar, size_t index,			\
     type *elem, size_t len) {								\
 	ltk_array_prepare_gap_##name(ar, index, len);					\
-	ltk_array_resize_##name(ar, ar->len + len);					\
+	/*ltk_array_resize_##name(ar, ar->len + len);*/					\
 	for (int i = 0; i < len; i++) {							\
 		ar->buf[index + i] = elem[i];						\
 	}										\
diff --git a/button.c b/button.c
@@ -21,6 +21,7 @@
  * SOFTWARE.
  */
 
+#include <stdio.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include "khash.h"
@@ -147,7 +148,7 @@ void ltk_draw_button(LtkButton *button)
 	XPutImage(ltk_global->display, window->xwindow, window->gc, img, 0, 0, text_x, text_y, button->tl->w, button->tl->h);
 }
 
-LtkButton *ltk_create_button(LtkWindow *window, const char *text, void (*callback) (void))
+LtkButton *ltk_create_button(LtkWindow *window, const char *text, void (*callback) (void *, XEvent, void *), void *data)
 {
 	LtkButton *button = malloc(sizeof(LtkButton));
 
@@ -159,6 +160,7 @@ LtkButton *ltk_create_button(LtkWindow *window, const char *text, void (*callbac
 	button->widget.mouse_release = <k_button_mouse_release;
 
 	button->callback = callback;
+	button->data = data;
 	LtkTheme *theme = ltk_global->theme;
 	button->tl = ltk_create_text_line(ltk_global->tm, text, ltk_global->tm->default_font, theme->button->font_size);
 	button->widget.rect.w = button->tl->w + (theme->button->border_width + theme->button->pad) * 2;
@@ -188,9 +190,8 @@ void ltk_destroy_button(LtkButton *button)
 
 /* FIXME: is the fixme below supposed to be for the function above? */
 /* FIXME: ungrid button if gridded */
-void ltk_button_mouse_release(LtkButton *button, XEvent event)
-{
+void ltk_button_mouse_release(LtkButton *button, XEvent event) {
 	if (button->widget.state == LTK_HOVERACTIVE && button->callback) {
-		button->callback();
+		button->callback(button, event, button->data);
 	}
 }
diff --git a/button.h b/button.h
@@ -28,7 +28,8 @@
 
 typedef struct {
 	LtkWidget widget;
-	void (*callback) (void);
+	void (*callback) (void *, XEvent, void *);
+	void *data;
 	LtkTextLine *tl;
 	XImage *text;
 	XImage *text_hover;
@@ -61,7 +62,7 @@ typedef struct LtkButtonTheme {
 
 void ltk_draw_button(LtkButton *button);
 
-LtkButton *ltk_create_button(LtkWindow * window, const char *text, void (*callback) (void));
+LtkButton *ltk_create_button(LtkWindow * window, const char *text, void (*callback) (void *, XEvent, void *), void *data);
 
 void ltk_destroy_button(LtkButton *button);
 
diff --git a/test1.c b/test1.c
@@ -1,11 +1,11 @@
 #include "ltkx.h"
 
-void bob1(void)
+void bob1(void *widget, XEvent event, void *data)
 {
 	printf("bob\n");
 }
 
-void bob2(void *widget, XEvent event)
+void bob2(void *widget, XEvent event, void *data)
 {
 	LtkButton *button = widget;
 	if (button->widget.state == LTK_HOVERACTIVE) {
@@ -13,6 +13,10 @@ void bob2(void *widget, XEvent event)
 	}
 }
 
+void bob3(LtkButton *button, XEvent event, LtkTextEdit *edit) {
+	ltk_text_edit_insert_text(edit, "asd");
+}
+
 int main(int argc, char *argv[])
 {
 	ltk_init("themes/default.ini");
@@ -25,18 +29,18 @@ int main(int argc, char *argv[])
 	ltk_set_column_weight(grid1, 0, 1);
 	ltk_set_column_weight(grid1, 1, 1);
 	/* Test callback functions */
-	LtkButton *button1 = ltk_create_button(window1, "I'm a button!", &bob1);
+	LtkButton *button1 = ltk_create_button(window1, "I'm a button!", &bob1, NULL);
 	ltk_grid_widget(button1, grid1, 0, 0, 1, 1, LTK_STICKY_LEFT | LTK_STICKY_RIGHT);
 	/* Test manual callback functions */
-	LtkButton *button2 = ltk_create_button(window1, "I'm a button!", NULL);
+	LtkButton *button2 = ltk_create_button(window1, "I'm a button!", NULL, NULL);
 	button2->widget.mouse_release = &bob2;
 	ltk_grid_widget(button2, grid1, 0, 1, 1, 1, LTK_STICKY_TOP | LTK_STICKY_BOTTOM);
 	//LtkButton *button3 = ltk_create_button(window1, "I'm a button!", NULL);
 	//ltk_grid_widget(button3, grid1, 1, 0, 1, 1, LTK_STICKY_TOP | LTK_STICKY_BOTTOM | LTK_STICKY_RIGHT);
 	//LtkButton *button4 = ltk_create_button(window1, "I'm a button!", NULL);
-	LtkButton *button4 = ltk_create_button(window1, "ہمارے بارے میں blablabla", NULL);
 	//LtkButton *button4 = ltk_create_button(window1, "پَیدایش", NULL);
 	LtkTextEdit *edit = ltk_create_text_edit(window1, "ہمارے بارے میں blablabla");
+	LtkButton *button4 = ltk_create_button(window1, "ہمارے بارے میں blablabla", &bob3, edit);
 	ltk_grid_widget(button4, grid1, 1, 0, 1, 1, LTK_STICKY_TOP | LTK_STICKY_BOTTOM | LTK_STICKY_RIGHT);
 	ltk_grid_widget(edit, grid1, 1, 1, 1, 1, LTK_STICKY_LEFT | LTK_STICKY_BOTTOM | LTK_STICKY_TOP);
 	ltk_mainloop();
diff --git a/text-hb.c b/text-hb.c
@@ -226,10 +226,6 @@ ltk_create_text_segment(LtkTextManager *tm, uint32_t *text, unsigned int len, ui
 	hb_buffer_set_direction(buf, dir);
 	hb_buffer_set_script(buf, script);
 	hb_buffer_add_utf32(buf, ts->str, len, 0, len);
-	for (int i = 0; i < len; i++) {
-		printf("%d\n", ts->str[i]);
-	}
-	printf("\n");
 	/* According to https://harfbuzz.github.io/the-distinction-between-levels-0-and-1.html
 	 * this should be level 1 clustering instead of level 0 */
 	hb_buffer_set_cluster_level(buf, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
diff --git a/text_buffer.c b/text_buffer.c
@@ -146,6 +146,7 @@ ltk_render_text_line_new(
 			index = par_is_rtl ? cur->num_glyphs - k - 1 : k;
 			glyph = &cur->glyphs[index];
 			x = par_is_rtl ? max_width - ((tl->w - glyph->x_abs) - cur_line_x) : glyph->x_abs - cur_line_x;
+			/* FIXME: use the computed indeces from above */
 			if (par_is_rtl && x < 0) {
 				cur_line++;
 				cur_line_x = (tl->w - glyph->x_abs - glyph->info->w);
@@ -339,9 +340,6 @@ ltk_text_line_itemize(struct ltk_text_line *tl) {
 	size_t end_index;
 	hb_direction_t dir;
 	int par_is_rtl = FRIBIDI_IS_RTL(tl->dir);
-	for (int i = 0; i < tl->len; i++) {
-		printf("%d, %d, %d, %d\n", tl->bidi_levels->buf[i], tl->scripts->buf[i], tl->log2vis->buf[i], tl->vis2log->buf[i]);
-	}
 	while (start_index < tl->len) {
 		end_index = start_index;
 		cur_level = last_level = tl->bidi_levels->buf[tl->vis2log->buf[start_index]];
@@ -358,8 +356,12 @@ ltk_text_line_itemize(struct ltk_text_line *tl) {
 		dir = HB_DIRECTION_LTR;
 		if (FRIBIDI_LEVEL_IS_RTL(last_level))
 			dir = HB_DIRECTION_RTL;
+		size_t start_log = tl->vis2log->buf[start_index];
+		size_t end_log = tl->vis2log->buf[end_index - 1];
+		if (start_log > end_log)
+			start_log = end_log;
 		new = ltk_text_run_create(
-		    start_index, end_index - start_index, last_script, dir);
+		    start_log, end_index - start_index, last_script, dir);
 		if (!first_run) {
 			first_run = new;
 		} else {
@@ -397,12 +399,15 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
 
 	buf = hb_buffer_create();
 	/* Harfbuzz requires the original, non-reversed text.
-	   Yes, I know this is a bit hacky */
+	   Yes, I know this is a bit hacky
+	   Update: This is now done in the ltk_text_line_itemize already */
+	/*
 	size_t start_index = tl->vis2log->buf[tr->start_index];
 	size_t end_index = tl->vis2log->buf[tr->start_index + tr->len - 1];
 	if (start_index > end_index)
 		start_index = end_index;
-	hb_buffer_add_utf32(buf, tl->log_buf->buf, tl->len, start_index, tr->len);
+	*/
+	hb_buffer_add_utf32(buf, tl->log_buf->buf, tl->len, tr->start_index, tr->len);
 	hb_buffer_set_direction(buf, tr->dir);
 	hb_buffer_set_script(buf, tr->script);
 	/* According to https://harfbuzz.github.io/the-distinction-between-levels-0-and-1.html
@@ -412,10 +417,6 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
 	ginf = hb_buffer_get_glyph_infos(buf, &tr->num_glyphs);
 	gpos = hb_buffer_get_glyph_positions(buf, &tr->num_glyphs);
 	float scale = stbtt_ScaleForMappingEmToPixels(&tr->font->info, font_size);
-	for (int i = start_index; i < start_index + tr->len; i++) {
-		printf("%d   %d\n", tl->log_buf->buf[i], tr->len);
-	}
-	printf("\n");
 
 	int x_min = INT_MAX, x_max = INT_MIN, y_min = INT_MAX, y_max = INT_MIN;
 	int x_abs = 0, y_abs = 0, x1_abs, y1_abs, x2_abs, y2_abs;
@@ -476,7 +477,8 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) {
 	tl->w = tl->h = 0;
 	int x_max, y_max;
 	while (run) {
-		FcPattern *pat = FcPatternDuplicate(tm->fcpattern);
+		/* Question: Why does this not work with Duplicate? */
+		FcPattern *pat = FcPatternCreate();//FcPatternDuplicate(tm->fcpattern);
 		FcPattern *match;
 		FcResult result;
 		FcPatternAddBool(pat, FC_SCALABLE, 1);
@@ -484,7 +486,7 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) {
 		FcDefaultSubstitute(pat);
 		FcCharSet *cs = FcCharSetCreate();
 		for (size_t i = run->start_index; i < run->start_index + run->len; i++) {
-			FcCharSetAddChar(cs, tl->vis_buf->buf[i]);
+			FcCharSetAddChar(cs, tl->log_buf->buf[i]);
 		}
 		FcPatternAddCharSet(pat, FC_CHARSET, cs);
 		match = FcFontMatch(NULL, pat, &result);
@@ -493,7 +495,6 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) {
 		uint16_t font_id = ltk_get_font(tm, file);
 		khint_t k = kh_get(fontstruct, tm->font_cache, font_id);
 		run->font = kh_value(tm->font_cache, k);
-		fflush(stdout);
 		FcPatternDestroy(match);
 		FcPatternDestroy(pat);
 		ltk_text_run_shape(tm, run, tl, tl->font_size, font_id, &y_max);
@@ -588,12 +589,12 @@ ltk_text_line_insert_text(struct ltk_text_line *tl, uint32_t *text, size_t len) 
 	hb_unicode_funcs_t *ufuncs = hb_unicode_funcs_get_default();
 	for (int i = 0; i < len; i++)
 		tl->scripts->buf[tl->cursor_pos + i] = hb_unicode_script(ufuncs, text[i]);
-	ltk_array_resize_uint32(tl->vis_buf, tl->vis_buf->len + len);
-	ltk_array_resize_int(tl->log2vis, tl->log2vis->len + len);
-	ltk_array_resize_int(tl->vis2log, tl->vis2log->len + len);
-	ltk_array_resize_level(tl->bidi_levels, tl->bidi_levels->len + len);
+	ltk_array_resize_uint32(tl->vis_buf, tl->len + len);
+	ltk_array_resize_int(tl->log2vis, tl->len + len);
+	ltk_array_resize_int(tl->vis2log, tl->len + len);
+	ltk_array_resize_level(tl->bidi_levels, tl->len + len);
 	tl->len += len;
-	tl->cursor_pos += len;
+	/*tl->cursor_pos += len;*/ /* FIXME */
 	/* FIXME: Why am I passing tm? It's global anyways */
 	ltk_text_line_recalculate(ltk_global->tm, tl);
 }
diff --git a/text_edit.c b/text_edit.c
@@ -49,7 +49,8 @@ ltk_draw_text_edit(LtkTextEdit *te) {
 	XPutImage(ltk_global->display, window->xwindow, window->gc, te->img, 0, 0, rect.x, rect.y, te->img->width, te->img->height);
 }
 
-LtkTextEdit *ltk_create_text_edit(LtkWindow *window, const char *text) {
+LtkTextEdit *
+ltk_create_text_edit(LtkWindow *window, const char *text) {
 	LtkTextEdit *te = malloc(sizeof(LtkTextEdit));
 	if (!te)
 		ltk_fatal("ERROR: Unable to allocate memory for LtkTextEdit.\n");
@@ -59,6 +60,16 @@ LtkTextEdit *ltk_create_text_edit(LtkWindow *window, const char *text) {
 	te->img = NULL;
 	return te;
 }
+
+void
+ltk_text_edit_insert_text(LtkTextEdit *te, const char *text) {
+	ltk_text_line_insert_utf8(te->tl, text);
+	if (te->img) XDestroyImage(te->img);
+	te->img = NULL;
+	/* FIXME: Need to "queue redraw" for whole window */
+	ltk_draw_text_edit(te);
+}
+
 void ltk_destroy_text_edit(LtkTextEdit *te) {
 	ltk_text_line_destroy(te->tl);
 	if (te->img) XDestroyImage(te->img);
diff --git a/text_edit.h b/text_edit.h
@@ -33,6 +33,7 @@ typedef struct {
 /* FIXME: standardize ltk_<widget>_destroy, etc. instead of ltk_destroy_<widget> */
 void ltk_draw_text_edit(LtkTextEdit *te);
 LtkTextEdit *ltk_create_text_edit(LtkWindow *window, const char *text);
+void ltk_text_edit_insert_text(LtkTextEdit *te, const char *text);
 void ltk_destroy_text_edit(LtkTextEdit *te);
 
 #endif /* _LTK_TEXT_EDIT_H_ */