URI: 
       tFix errors with resizing arrays; test inserting text - ltkx - GUI toolkit for X11 (WIP)
  HTML git clone git://lumidify.org/ltkx.git
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 0e40d68a8b98ca331bfad96d3293d9c01c5875ca
   DIR parent 440540f9caf405888a176c460cffff8669478b9e
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Fri, 15 May 2020 09:39:58 +0200
       
       Fix errors with resizing arrays; test inserting text
       
       Diffstat:
         M array.h                             |       7 ++++---
         M button.c                            |       9 +++++----
         M button.h                            |       5 +++--
         M test1.c                             |      14 +++++++++-----
         M text-hb.c                           |       4 ----
         M text_buffer.c                       |      37 ++++++++++++++++---------------
         M text_edit.c                         |      13 ++++++++++++-
         M text_edit.h                         |       1 +
       
       8 files changed, 53 insertions(+), 37 deletions(-)
       ---
   DIR diff --git a/array.h b/array.h
       t@@ -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];                                                \
                }                                                                                \
   DIR diff --git a/button.c b/button.c
       t@@ -21,6 +21,7 @@
         * SOFTWARE.
         */
        
       +#include <stdio.h>
        #include <X11/Xlib.h>
        #include <X11/Xutil.h>
        #include "khash.h"
       t@@ -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));
        
       t@@ -159,6 +160,7 @@ LtkButton *ltk_create_button(LtkWindow *window, const char *text, void (*callbac
                button->widget.mouse_release = &ltk_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;
       t@@ -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);
                }
        }
   DIR diff --git a/button.h b/button.h
       t@@ -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;
       t@@ -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);
        
   DIR diff --git a/test1.c b/test1.c
       t@@ -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) {
       t@@ -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");
       t@@ -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();
   DIR diff --git a/text-hb.c b/text-hb.c
       t@@ -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);
   DIR diff --git a/text_buffer.c b/text_buffer.c
       t@@ -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);
       t@@ -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]];
       t@@ -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 {
       t@@ -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
       t@@ -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;
       t@@ -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);
       t@@ -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);
       t@@ -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);
       t@@ -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);
        }
   DIR diff --git a/text_edit.c b/text_edit.c
       t@@ -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");
       t@@ -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);
   DIR diff --git a/text_edit.h b/text_edit.h
       t@@ -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_ */