URI: 
       tAdd various destroy functions for textedit - 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 02f8e7bfa579c4947e8cab78a38f6b2344d4d123
   DIR parent 487c86781fe1af79c0677565dea2aa35049c082c
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Wed, 13 May 2020 18:36:41 +0200
       
       Add various destroy functions for textedit
       
       Diffstat:
         M textedit_wip.c                      |      82 +++++++++++++++++++++++++------
         M textedit_wip.h                      |       2 ++
       
       2 files changed, 70 insertions(+), 14 deletions(-)
       ---
   DIR diff --git a/textedit_wip.c b/textedit_wip.c
       t@@ -49,7 +49,7 @@ LTK_ARRAY_INIT_IMPL(int, int)
        LTK_STACK_INIT_IMPL(script, int, hb_script_t, pair_index, script);
        
        /* based on http://codemadness.org/git/dwm-font/file/drw.c.html#l315 */
       -XImage *
       +void
        ltk_render_text_line(
                struct ltk_text_line *tl,
                int max_width,
       t@@ -88,20 +88,21 @@ ltk_render_text_line(
                        }
                } while (cur = cur->next);
        
       +        if (tl->img) XDestroyImage(tl->img);
                XWindowAttributes attrs;
                XGetWindowAttributes(dpy, window, &attrs);
                int depth = attrs.depth;
       -        XImage *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);
       +        tl->img = XCreateImage(dpy, CopyFromParent, depth, ZPixmap, 0, NULL, max_width, tl->h * tl->wrap_indeces->len, 32, 0);
       +        tl->img->data = calloc(img->bytes_per_line, img->height);
       +        XInitImage(tl->img);
        
                int b;
                for (int i = 0; i < tl->h * tl->wrap_indeces->len; i++) {
       -                b = img->bytes_per_line * i;
       +                b = tl->img->bytes_per_line * i;
                        for (int j = 0; j < max_width; j++) {
       -                        img->data[b++] = bg.blue / 257;
       -                        img->data[b++] = bg.green / 257;
       -                        img->data[b++] = bg.red / 257;
       +                        tl->img->data[b++] = bg.blue / 257;
       +                        tl->img->data[b++] = bg.green / 257;
       +                        tl->img->data[b++] = bg.red / 257;
                                b++;
                        }
                }
       t@@ -111,6 +112,7 @@ ltk_render_text_line(
                int cur_line_x = 0;
                int cur_line = 0;
                LtkGlyph *glyph;
       +        /* FIXME: Ints are compared with size_t's in various places. Maybe I should fix that. */
                /* FIXME: how should an empty line be handled? This doesn't use a do-for
                   loop in case tl->first_run is NULL, but I should probably decide what
                   to do in that case */
       t@@ -126,18 +128,16 @@ ltk_render_text_line(
                                y = glyph->y_abs + tl->h * cur_line;
                                for (int i = 0; i < glyph->info->h; i++) {
                                        for (int j = 0; j < glyph->info->w; j++) {
       -                                        b = (y + i) * img->bytes_per_line + (x + j) * 4;
       +                                        b = (y + i) * tl->img->bytes_per_line + (x + j) * 4;
                                                a = glyph->info->alphamap[i * glyph->info->w + j] / 255.0;
       -                                        img->data[b] = (fg.blue * a + (1 - a) * (uint16_t)img->data[b] * 257) / 257;
       -                                        img->data[b + 1] = (fg.green * a + (1 - a) * (uint16_t)img->data[b + 1] * 257) / 257;
       -                                        img->data[b + 2] = (fg.red * a + (1 - a) * (uint16_t)img->data[b + 2] * 257) / 257;
       +                                        tl->img->data[b] = (fg.blue * a + (1 - a) * (uint16_t)tl->img->data[b] * 257) / 257;
       +                                        tl->img->data[b + 1] = (fg.green * a + (1 - a) * (uint16_t)tl->img->data[b + 1] * 257) / 257;
       +                                        tl->img->data[b + 2] = (fg.red * a + (1 - a) * (uint16_t)tl->img->data[b + 2] * 257) / 257;
                                        }
                                }
                        }
                        cur = cur->next;
                }
       -
       -        return img;
        }
        
        /*
       t@@ -360,6 +360,7 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
                khash_t(glyphinfo) *glyph_cache;
                khint_t k;
        
       +        tr->font_id = font_id;
                uint32_t attr = font_id << 16 + font_size;
                /* FIXME: turn this into ltk_get_glyph_cache */
                k = kh_get(glyphcache, tm->glyph_cache, attr);
       t@@ -502,6 +503,45 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) {
                }
        }
        
       +/* FIXME: Don't destroy fonts, etc. every time the line is recalculated */
       +/* Maybe decrease font refs but don't destroy until after the runs have been re-shaped */
       +void
       +ltk_text_run_destroy(struct ltk_text_line *tl, struct ltk_text_run *tr) {
       +        khash_t(glyphinfo) *gcache;
       +        LtkFont *font;
       +        LtkGlyph *glyph;
       +        khint_t k;
       +        k = kh_get(glyphinfo, ltk_global->tm->glyph_cache, tr->font_id << 16 + tl->font_size);
       +        gcache = kh_value(ltk_global->tm->glyph_cache, k);
       +        for (int i = 0; i < tr->len; i++) {
       +                glyph = tr->glyphs[i];
       +                if (--glyph->info->refs < 1) {
       +                        k = kh_get(glyphinfo, cache, glyph->info->id);
       +                        kh_del(glyphinfo, cache, k);
       +                        ltk_destroy_glyph_info(glyph->info);
       +                }
       +        }
       +        k = kh_get(fontstruct, ltk_global->tm->font_cache, tr->font_id);
       +        font = kh_value(ltk_global->tm->font_cache, k);
       +        if (--font->refs < 1) {
       +                kh_del(fontstruct, ltk_global->tm->font_cache, k);
       +                ltk_destroy_font(font);
       +        }
       +        free(tr->glyphs);
       +        free(tr);
       +}
       +
       +void
       +ltk_text_line_destroy_runs(struct ltk_text_line *tl) {
       +        struct ltk_text_run *cur, *last;
       +        cur = tl->first_run;
       +        while (cur) {
       +                last = cur;
       +                ltk_text_run_destroy(cur);
       +                cur = last->next;
       +        }
       +}
       +
        static void
        ltk_text_line_recalculate(LtkTextManager *tm, struct ltk_text_line *tl) {
                ltk_gap_buffer_clear_uint32(tl->vis_buf);
       t@@ -590,3 +630,17 @@ ltk_text_buffer_create(void) {
                buf->cur_line = buf->head;
                buf->line_gap = 0;
        }
       +
       +void
       +ltk_text_line_destroy(struct ltk_text_line *tl) {
       +        ltk_gap_buffer_destroy_uint32(tl->log_buf);
       +        ltk_gap_buffer_destroy_uint32(tl->vis_buf);
       +        ltk_gap_buffer_destroy_script(tl->scripts);
       +        ltk_gap_buffer_destroy_int(tl->log2vis);
       +        ltk_gap_buffer_destroy_int(tl->vis2log);
       +        ltk_array_destroy_level(tl->bidi_levels);
       +        ltk_array_destroy_int(tl->wrap_indeces);
       +        ltk_text_line_destroy_runs(tl);
       +        if (tl->img) XDestroyImage(tl->img);
       +        free(tl);
       +}
   DIR diff --git a/textedit_wip.h b/textedit_wip.h
       t@@ -55,6 +55,7 @@ struct ltk_text_run {
                int start_y;
                int w;
                LtkFont *font;
       +        uint16_t font_id;
                hb_script_t script;
                hb_direction_t dir;
        }
       t@@ -79,6 +80,7 @@ struct ltk_text_line {
                int y_min;
                int w;
                int h;
       +        XImage *img;
        };
        
        struct ltk_text_buffer {