URI: 
       tFix font cache - 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 5fd0eb1d2fa742e6ea257992acb0edee773b6f24
   DIR parent 30f6302a0a754c310140abbb88f467492586be68
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Thu, 14 May 2020 17:37:12 +0200
       
       Fix font cache
       
       Diffstat:
         M array.h                             |       1 -
         M test1.c                             |      15 ++++++++-------
         M text-common.c                       |       3 ++-
         M text_buffer.c                       |      54 +++++++++++++++----------------
         M text_buffer.h                       |       6 ++++++
         M text_edit.c                         |       3 ---
       
       6 files changed, 42 insertions(+), 40 deletions(-)
       ---
   DIR diff --git a/array.h b/array.h
       t@@ -133,7 +133,6 @@ ltk_array_resize_##name(struct ltk_array_##name *ar, size_t len) {                        \
                                                                                                \
        void                                                                                        \
        ltk_array_destroy_##name(struct ltk_array_##name *ar) {                                        \
       -        printf("%p   %p   %d\n", ar->buf, ar, ar->buf_size);                                \
                free(ar->buf);                                                                        \
                ar->buf = NULL;                                                                        \
                free(ar);                                                                        \
   DIR diff --git a/test1.c b/test1.c
       t@@ -25,18 +25,19 @@ 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);
       -        //ltk_grid_widget(button1, grid1, 0, 0, 1, 1, LTK_STICKY_LEFT | LTK_STICKY_RIGHT);
       +        LtkButton *button1 = ltk_create_button(window1, "I'm a button!", &bob1);
       +        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);
       -        //button2->widget.mouse_release = &bob2;
       -        //ltk_grid_widget(button2, grid1, 0, 1, 1, 1, LTK_STICKY_TOP | LTK_STICKY_BOTTOM);
       +        LtkButton *button2 = ltk_create_button(window1, "I'm a button!", 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, "ہمارے بارے میں blablabla", NULL);
                //LtkButton *button4 = ltk_create_button(window1, "پَیدایش", NULL);
                LtkTextEdit *edit = ltk_create_text_edit(window1, "ہمارے بارے میں blablabla");
       -        ltk_grid_widget(edit, grid1, 1, 1, 1, 1, LTK_STICKY_LEFT | LTK_STICKY_BOTTOM);
       +        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_STICKY_RIGHT);
                ltk_mainloop();
        }
   DIR diff --git a/text-common.c b/text-common.c
       t@@ -120,7 +120,8 @@ ltk_init_text(char *font_name)
                tm->font_paths = kh_init(fontid);
                tm->font_cache = kh_init(fontstruct);
                tm->glyph_cache = kh_init(glyphcache);
       -        tm->font_id_cur = 0;
       +        /* FIXME: THIS REALLY SHOULD NOT BE UINT16_T! IT GETS MESSY WITH BIT-SHIFTING */
       +        tm->font_id_cur = 1;
                ltk_load_default_font(tm, font_name);
        
                return tm;
   DIR diff --git a/text_buffer.c b/text_buffer.c
       t@@ -64,12 +64,12 @@ ltk_render_text_line_new(
                int cur_y = 0;
                int cur_x = par_is_rtl ? max_width : 0;
                ltk_array_clear_int(tl->wrap_indeces);
       -        ltk_array_append_int(tl->wrap_indeces, 0);
       +        ltk_array_append_uint32(tl->wrap_indeces, 0);
        
                /* FIXME: wrap bidi text properly */
                /* FIXME: THIS IS UGLY */
       -        struct ltk_text_run *cur = tl->first_run;
       -        do {
       +        struct ltk_text_run *cur = par_is_rtl ? tl->last_run : tl->first_run;
       +        while (cur) {
                        if (par_is_rtl) {
                                for (int i = cur->num_glyphs - 1; i >= 0; i--) {
                                        cur_x -= cur->glyphs[i].x_advance;
       t@@ -85,7 +85,7 @@ ltk_render_text_line_new(
                                                }
                                                i = j;
                                                /* FIXME: handle case that this is the same as the last index */
       -                                        ltk_array_append_int(tl->wrap_indeces, cur->glyphs[i].cluster);
       +                                        ltk_array_append_uint32(tl->wrap_indeces, cur->glyphs[i].cluster);
                                                cur_x = max_width;
                                        }
                                }
       t@@ -104,21 +104,20 @@ ltk_render_text_line_new(
                                                }
                                                i = j;
                                                /* FIXME: handle case that this is the same as the last index */
       -                                        ltk_array_append_int(tl->wrap_indeces, cur->glyphs[i].cluster);
       +                                        ltk_array_append_uint32(tl->wrap_indeces, cur->glyphs[i].cluster);
                                                cur_x = 0;
                                        }
                                }
                        }
       -        } while (cur = cur->next);
       +                cur = par_is_rtl ? cur->last : cur->next;
       +        }
        
                XWindowAttributes attrs;
                XGetWindowAttributes(dpy, window, &attrs);
                int depth = attrs.depth;
       -        printf("%d ---  %d\n", max_width, tl->h * tl->wrap_indeces->len);
                img = XCreateImage(dpy, CopyFromParent, depth, ZPixmap, 0, NULL, max_width, tl->h * tl->wrap_indeces->len, 32, 0);
                img->data = calloc(img->bytes_per_line, img->height);
                XInitImage(img);
       -        printf("%d +++  %d\n", img->width, img->height);
        
                int b;
                for (int i = 0; i < tl->h * tl->wrap_indeces->len; i++) {
       t@@ -131,7 +130,7 @@ ltk_render_text_line_new(
                        }
                }
        
       -        cur = tl->first_run;
       +        cur = par_is_rtl ? tl->last_run : tl->first_run;
                int x, y;
                double a;
                int cur_line_x = 0;
       t@@ -142,20 +141,21 @@ ltk_render_text_line_new(
                   loop in case tl->first_run is NULL, but I should probably decide what
                   to do in that case */
                int index;
       +        cur_x = max_width;
                while (cur) {
                        for (int k = 0; k < cur->num_glyphs; k++) {
       -                        index = par_is_rtl ? cur->num_glyphs - k - 1 : k;
       -                        glyph = &cur->glyphs[k];
       -                        if (cur_line < tl->wrap_indeces->len - 1 &&
       -                            ((!par_is_rtl && glyph->cluster >= tl->wrap_indeces->buf[cur_line + 1]) ||
       -                             (par_is_rtl && glyph->cluster <= tl->wrap_indeces->buf[cur_line + 1]))) {
       +                        index = HB_DIRECTION_IS_BACKWARD(cur->dir) ? cur->num_glyphs - k - 1 : k;
       +                        glyph = &cur->glyphs[index];
       +                        cur_x -= glyph->x_advance;
       +                        if (cur_x < 0) {
       +                                cur_x = max_width - glyph->x_advance;
                                        cur_line++;
                                        cur_line_x += glyph->x_abs - cur_line_x;
       +                                x = max_width - (glyph->x_abs - cur_line_x) - glyph->info->w;
                                }
       -                        x = par_is_rtl ? max_width - (glyph->x_abs - cur_line_x) - glyph->info->w: glyph->x_abs - cur_line_x;
       +                        //x = par_is_rtl ? max_width - (glyph->x_abs - cur_line_x) - glyph->info->w : glyph->x_abs - cur_line_x;
       +                        x = cur_x;
                                y = glyph->y_abs + tl->h * cur_line;
       -                        printf("%d,%d\n", x, y);
       -                        fflush(stdout);
                                if (x < 0)
                                        x = 0;
                                if (x > max_width - glyph->info->w)
       t@@ -174,7 +174,7 @@ ltk_render_text_line_new(
                                        }
                                }
                        }
       -                cur = cur->next;
       +                cur = par_is_rtl ? cur->last : cur->next;
                }
                return img;
        }
       t@@ -320,6 +320,7 @@ ltk_text_run_create(size_t start_index, size_t len, hb_script_t script, hb_direc
                run->script = script;
                run->dir = dir;
                run->next = NULL;
       +        run->last = NULL;
                return run;
        }
        
       t@@ -355,15 +356,14 @@ ltk_text_line_itemize(struct ltk_text_line *tl) {
                        if (!first_run) {
                                first_run = new;
                        } else {
       -                        if (par_is_rtl)
       -                                new->next = cur_run;
       -                        else
       -                                cur_run->next = new;
       +                        cur_run->next = new;
       +                        new->last = cur_run;
                        }
                        cur_run = new;
                        start_index = end_index;
                }
       -        tl->first_run = par_is_rtl ? cur_run : first_run;
       +        tl->first_run = first_run;
       +        tl->last_run = cur_run;
        }
        
        static void
       t@@ -462,7 +462,6 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) {
                        FcPattern *pat = FcPatternDuplicate(tm->fcpattern);
                        FcPattern *match;
                        FcResult result;
       -                printf("%p\n", pat);
                        FcPatternAddBool(pat, FC_SCALABLE, 1);
                        FcConfigSubstitute(NULL, pat, FcMatchPattern);
                        FcDefaultSubstitute(pat);
       t@@ -501,7 +500,7 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) {
                        for (int i = 0; i < run->len; i++) {
                                glyph = &run->glyphs[i];
                                glyph->x_abs = cur_x + glyph->info->xoff + glyph->x_offset;
       -                        glyph->y_abs = cur_y - glyph->info->yoff - glyph->y_offset;
       +                        glyph->y_abs = cur_y + glyph->info->yoff - glyph->y_offset;
                                cur_x += glyph->x_advance;
                                cur_y -= glyph->y_advance;
                        }
       t@@ -549,7 +548,6 @@ ltk_text_line_destroy_runs(struct ltk_text_run *runs) {
        
        static void
        ltk_text_line_recalculate(LtkTextManager *tm, struct ltk_text_line *tl) {
       -        printf("%d,%d,%d,%d,%d\n", tl->log_buf->buf_size, tl->vis_buf->buf_size, tl->log2vis->buf_size, tl->vis2log->buf_size, tl->bidi_levels->buf_size);
                fribidi_log2vis(
                    tl->log_buf->buf, tl->log_buf->len,
                    &tl->dir, tl->vis_buf->buf, tl->log2vis->buf, tl->vis2log->buf, tl->bidi_levels->buf
       t@@ -608,7 +606,7 @@ ltk_text_line_create(void) {
                line->vis2log = ltk_array_create_int(4);
                line->scripts = ltk_array_create_script(4);
                line->bidi_levels = ltk_array_create_level(4);
       -        line->wrap_indeces = ltk_array_create_int(1);
       +        line->wrap_indeces = ltk_array_create_uint32(1);
                line->first_run = NULL;
                line->cur_run = NULL;
                line->next = NULL;
       t@@ -644,7 +642,7 @@ ltk_text_line_destroy(struct ltk_text_line *tl) {
                ltk_array_destroy_int(tl->log2vis);
                ltk_array_destroy_int(tl->vis2log);
                ltk_array_destroy_level(tl->bidi_levels);
       -        ltk_array_destroy_int(tl->wrap_indeces);
       +        ltk_array_destroy_uint32(tl->wrap_indeces);
                ltk_text_line_destroy_runs(tl->first_run);
                free(tl);
        }
   DIR diff --git a/text_buffer.h b/text_buffer.h
       t@@ -42,6 +42,7 @@ struct ltk_text_run {
                LtkGlyph *glyphs;
                unsigned int num_glyphs;
                struct ltk_text_run *next;
       +        struct ltk_text_run *last;
                size_t start_index;
                size_t len; /* FIXME: THIS IS NOT THE NUMBER OF GLYPHS; IT IS THE ACTUAL NUMBER OF CHARACTERS REPRESENTED BY THIS RUN */
                int start_x;
       t@@ -54,6 +55,11 @@ struct ltk_text_run {
                hb_direction_t dir;
        };
        
       +struct ltk_line_break {
       +        size_t index;
       +        struct ltk_text_run *run;
       +};
       +
        struct ltk_text_line {
                struct ltk_array_uint32 *log_buf; /* buffer of the logical text */
                struct ltk_array_script *scripts;
   DIR diff --git a/text_edit.c b/text_edit.c
       t@@ -46,9 +46,6 @@ ltk_draw_text_edit(LtkTextEdit *te) {
                LtkWindow *window = te->widget.window;
                if (!te->img)
                        te->img = ltk_render_text_line_new(te->tl, rect.w, ltk_global->display, window->xwindow, window->gc, ltk_global->colormap, fg, bg);
       -        printf("%p\n", te->img);
       -        fflush(stdout);
       -        printf("%d,%d;%d,%d;%d,%d\n", rect.x, rect.y, rect.w, rect.h, te->img->width, te->img->height);
                XPutImage(ltk_global->display, window->xwindow, window->gc, te->img, 0, 0, rect.x, rect.y, te->img->width, te->img->height);
        }