URI: 
       tSomewhat improve drawing - 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 d6e2f851b663e5db6957c3fb5c41f595c139c3c6
   DIR parent 288e467a6083a547a3996e69b6ba0ea1d430e70b
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Wed, 27 May 2020 21:19:10 +0200
       
       Somewhat improve drawing
       
       Diffstat:
         M NOTES                               |       3 +++
         M ltk.c                               |      42 ++++++++++++++++++-------------
         M ltk.h                               |       6 +++---
         M text_buffer.c                       |      36 -------------------------------
         M text_common.c                       |      80 -------------------------------
         M text_common.h                       |       7 -------
       
       6 files changed, 31 insertions(+), 143 deletions(-)
       ---
   DIR diff --git a/NOTES b/NOTES
       t@@ -36,3 +36,6 @@ and creates a "failsafe" error window (just using basic
        XDrawString, etc.) to show errors (like index out of bounds,
        etc.). Still print the error, of course, in case creating
        a window doesn't work.
       +
       +Idea: Make interface primarily key-driven; store keybindings
       +in config so they can easily be configured
   DIR diff --git a/ltk.c b/ltk.c
       t@@ -94,10 +94,19 @@ void ltk_mainloop(void)
                XEvent event;
                KeySym key;
                char text[255];
       +        int redraw = 0;
       +        LtkWindow *window = NULL;
        
       +        /* FIXME: compress motion events */
                while (1) {
       -                XNextEvent(ltk_global->display, &event);
       -                ltk_handle_event(event);
       +                if (XPending(ltk_global->display) || !redraw) {
       +                        XNextEvent(ltk_global->display, &event);
       +                        redraw = ltk_handle_event(event, &window) || redraw;
       +                } else if (redraw && window) {
       +                        ltk_redraw_window(window);
       +                        redraw = 0;
       +                        window = NULL;
       +                }
                }
        }
        
       t@@ -177,10 +186,10 @@ void ltk_destroy_window(LtkWindow * window)
                ltk_global->window_num--;
        }
        
       -void ltk_window_other_event(void *widget, XEvent event)
       +int ltk_window_other_event(LtkWindow *window, XEvent event)
        {
       -        LtkWindow *window = (LtkWindow *) widget;
                LtkWidget *ptr = window->root_widget;
       +        int retval = 0;
                if (event.type == ConfigureNotify) {
                        unsigned int w, h;
                        w = event.xconfigure.width;
       t@@ -194,16 +203,15 @@ void ltk_window_other_event(void *widget, XEvent event)
                                ptr->rect.w = w;
                                ptr->rect.h = h;
                                ptr->resize(ptr, orig_w, orig_h);
       -                        ltk_redraw_window(window);
       +                        retval = 1;
                        }
       -        }
       -        if (event.type == Expose && event.xexpose.count == 0) {
       -                ltk_redraw_window(window);
       -        }
       -        if (event.type == ClientMessage
       +        } else if (event.type == Expose && event.xexpose.count == 0) {
       +                retval = 1;
       +        } else if (event.type == ClientMessage
                    && event.xclient.data.l[0] == ltk_global->wm_delete_msg) {
                        ltk_remove_window(window);
                }
       +        return retval;
        }
        
        void ltk_window_ini_handler(LtkTheme *theme, const char *prop, const char *value)
       t@@ -405,14 +413,13 @@ void ltk_motion_notify_event(void *widget, XEvent event)
                        ptr->motion_notify(ptr, event);
        }
        
       -void ltk_handle_event(XEvent event)
       +int ltk_handle_event(XEvent event, LtkWindow **window)
        {
       -        LtkWindow *window;
                LtkWidget *root_widget;
                int k = kh_get(winhash, ltk_global->window_hash, event.xany.window);
       -        window = kh_value(ltk_global->window_hash, k);
       -        if (!window) return;
       -        root_widget = window->root_widget;
       +        *window = kh_value(ltk_global->window_hash, k);
       +        if (!*window) return 0;
       +        root_widget = (*window)->root_widget;
                switch (event.type) {
                case KeyPress:
                        break;
       t@@ -432,7 +439,8 @@ void ltk_handle_event(XEvent event)
                        break;
                default:
                        /* FIXME: users should be able to register other events like closing the window */
       -                if (window->other_event)
       -                        window->other_event(window, event);
       +                if ((*window)->other_event)
       +                        return (*window)->other_event(*window, event);
                }
       +        return 0;
        }
   DIR diff --git a/ltk.h b/ltk.h
       t@@ -83,7 +83,7 @@ typedef struct LtkWindow {
                Window xwindow;
                GC gc;
                void *root_widget;
       -        void (*other_event) (void *, XEvent event);
       +        int (*other_event) (LtkWindow *, XEvent event);
                LtkRect rect;
        } LtkWindow;
        
       t@@ -136,7 +136,7 @@ void ltk_remove_window(LtkWindow * window);
        
        void ltk_destroy_window(LtkWindow * window);
        
       -void ltk_window_other_event(void *widget, XEvent event);
       +int ltk_window_other_event(LtkWindow *window, XEvent event);
        
        void ltk_destroy_theme(LtkTheme * theme);
        
       t@@ -159,6 +159,6 @@ void ltk_mouse_release_event(void *widget, XEvent event);
        
        void ltk_motion_notify_event(void *widget, XEvent event);
        
       -void ltk_handle_event(XEvent event);
       +int ltk_handle_event(XEvent event, LtkWindow **window);
        
        #endif
   DIR diff --git a/text_buffer.c b/text_buffer.c
       t@@ -21,7 +21,6 @@
         * SOFTWARE.
         */
        
       -#include <sys/time.h>
        #include <stdio.h>
        #include <stdlib.h>
        #include <stdint.h>
       t@@ -79,10 +78,6 @@ ltk_text_line_cleanup_soft_lines(struct ltk_array_line *soft_lines, int old_len)
        
        void
        ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) {
       -        struct timeval t1, t2;
       -        gettimeofday(&t1, NULL);
       -        printf("wrap1: %d, %d\n", t1.tv_sec, t1.tv_usec);
       -
                tl->w_wrapped = max_width;
                int old_len = tl->soft_lines->len;
                tl->soft_lines->len = 0;
       t@@ -252,9 +247,6 @@ ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) {
                else
                        tl->w_wrapped = max_width;
                tl->h_wrapped = tl->soft_lines->len * tl->h;
       -
       -        gettimeofday(&t2, NULL);
       -        printf("wrap2: %d, %d, diff: %d\n", t2.tv_sec, t2.tv_usec, t2.tv_usec - t1.tv_usec);
        }
        
        XImage *
       t@@ -309,9 +301,6 @@ ltk_text_line_render(
                XColor fg,
                XColor bg)
        {
       -        struct timeval t1, t2;
       -        gettimeofday(&t1, NULL);
       -        printf("render1: %d, %d\n", t1.tv_sec, t1.tv_usec);
                LtkGlyph *glyph;
                int par_is_rtl = tl->dir == HB_DIRECTION_RTL;
        
       t@@ -389,8 +378,6 @@ ltk_text_line_render(
                        ltk_array_resize_int(sl->glyph_pos, sl->glyph_pos->len);
                        ltk_array_resize_uint32(sl->glyph_clusters, sl->glyph_clusters->len);
                }
       -        gettimeofday(&t2, NULL);
       -        printf("render2: %d, %d, diff: %d\n", t2.tv_sec, t2.tv_usec, t2.tv_usec - t1.tv_usec);
                return img;
        }
        
       t@@ -638,8 +625,6 @@ ltk_text_line_itemize(struct ltk_text_line *tl) {
        static void
        ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
            struct ltk_text_line *tl, uint16_t font_size, uint16_t font_id, int *ret_y_max) {
       -        struct timeval t1, t2;
       -        gettimeofday(&t1, NULL);
                khash_t(glyphinfo) *glyph_cache;
                khint_t k;
        
       t@@ -668,8 +653,6 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
                hb_shape(tr->font->hb, buf, NULL, 0);
                ginf = hb_buffer_get_glyph_infos(buf, &tr->num_glyphs);
                gpos = hb_buffer_get_glyph_positions(buf, &tr->num_glyphs);
       -        gettimeofday(&t2, NULL);
       -        printf("hb_shape: %d, %d, diff: %d\n", t2.tv_sec, t2.tv_usec, t2.tv_usec - t1.tv_usec);
                float scale = stbtt_ScaleForMappingEmToPixels(&tr->font->info, font_size);
        
                int x_min = INT_MAX, x_max = INT_MIN, y_min = INT_MAX, y_max = INT_MIN;
       t@@ -721,8 +704,6 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
                *ret_y_max = y_max;
        
                tr->font->refs++;
       -        gettimeofday(&t2, NULL);
       -        printf("run_shape: %d\n", t2.tv_usec - t1.tv_usec);
        }
        
        static void
       t@@ -732,10 +713,8 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) {
                int y_max;
                int y_max_overall = INT_MIN;
                int y_min_overall = INT_MAX;
       -        struct timeval t1, t2;
                while (run) {
                        /* Question: Why does this not work with FcPatternDuplicate? */
       -                gettimeofday(&t1, NULL);
                        FcPattern *pat = FcPatternCreate();
                        FcPattern *match;
                        FcResult result;
       t@@ -756,8 +735,6 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) {
                        run->font = kh_value(tm->font_cache, k);
                        FcPatternDestroy(match);
                        FcPatternDestroy(pat);
       -                gettimeofday(&t2, NULL);
       -                printf("fontconfig: %d\n", t2.tv_usec - t1.tv_usec);
                        ltk_text_run_shape(tm, run, tl, tl->font_size, font_id, &y_max);
                        if (y_max_overall < y_max)
                                y_max_overall = y_max;
       t@@ -828,31 +805,18 @@ ltk_text_line_destroy_runs(struct ltk_text_run *runs) {
        static void
        ltk_text_line_recalculate(LtkTextManager *tm, struct ltk_text_line *tl) {
                FriBidiCharType par_dir = FRIBIDI_TYPE_ON;
       -        struct timeval t1, t2;
       -        gettimeofday(&t1, NULL);
       -        printf("fribidi1: %d, %d\n", t1.tv_sec, t1.tv_usec);
                fribidi_log2vis(
                    tl->log_buf->buf, tl->log_buf->len,
                    &par_dir, tl->vis_buf->buf, tl->log2vis->buf, tl->vis2log->buf, tl->bidi_levels->buf
                );
       -        gettimeofday(&t2, NULL);
       -        printf("fribidi2: %d, %d, diff: %d\n", t2.tv_sec, t2.tv_usec, t2.tv_usec - t1.tv_usec);
                if (FRIBIDI_IS_RTL(par_dir))
                        tl->dir = HB_DIRECTION_RTL;
                else
                        tl->dir = HB_DIRECTION_LTR;
                struct ltk_text_run *old_runs = tl->first_run;
       -        gettimeofday(&t1, NULL);
       -        printf("itemize1: %d, %d\n", t1.tv_sec, t1.tv_usec);
                ltk_text_line_itemize(tl);
       -        gettimeofday(&t2, NULL);
       -        printf("itemize2: %d, %d, diff: %d\n", t2.tv_sec, t2.tv_usec, t2.tv_usec - t1.tv_usec);
                struct ltk_text_run *cur = tl->first_run;
       -        gettimeofday(&t1, NULL);
       -        printf("shape1: %d, %d\n", t1.tv_sec, t1.tv_usec);
                ltk_text_line_shape(tm, tl);
       -        gettimeofday(&t2, NULL);
       -        printf("shape2: %d, %d, diff: %d\n", t2.tv_sec, t2.tv_usec, t2.tv_usec - t1.tv_usec);
                /* this needs to be done after shaping so the fonts, etc. aren't
                   removed if their reference counts drop and then loaded again
                   right afterwards */
   DIR diff --git a/text_common.c b/text_common.c
       t@@ -328,83 +328,3 @@ ltk_destroy_glyph(LtkGlyph *glyph, khash_t(glyphinfo) *cache)
                }
                free(glyph);
        }
       -
       -#if 0
       -/* based on http://codemadness.org/git/dwm-font/file/drw.c.html#l315 */
       -XImage *
       -ltk_render_text_line(
       -        LtkTextLine *tl,
       -        Display *dpy,
       -        Window window,
       -        GC gc,
       -        Colormap colormap,
       -        XColor fg,
       -        XColor bg)
       -{
       -        XWindowAttributes attrs;
       -        XGetWindowAttributes(dpy, window, &attrs);
       -        int depth = attrs.depth;
       -        XImage *img = XCreateImage(dpy, CopyFromParent, depth, ZPixmap, 0, NULL, tl->w, tl->h, 32, 0);
       -        img->data = calloc(img->bytes_per_line, img->height);
       -        XInitImage(img);
       -        int b;
       -        for (int i = 0; i < tl->h; i++) {
       -                b = img->bytes_per_line * i;
       -                for (int j = 0; j < tl->w; j++) {
       -                        img->data[b++] = bg.blue / 257;
       -                        img->data[b++] = bg.green / 257;
       -                        img->data[b++] = bg.red / 257;
       -                        b++;
       -                }
       -        }
       -
       -        LtkTextSegment *ts = tl->start_segment;
       -        int x = 0;
       -        int y = 0;
       -        int is_hor = HB_DIRECTION_IS_HORIZONTAL(ts->dir);
       -        do {
       -                if (is_hor) {
       -                        y = tl->h - tl->y_max;
       -                        ltk_render_text_segment(ts, x + ts->start_x, y, img, fg);
       -                        x += ts->w;
       -                } else {
       -                        x = tl->w - tl->x_max;
       -                        ltk_render_text_segment(ts, x, y + ts->start_y, img, fg);
       -                        y += ts->h;
       -                }
       -        } while (ts = ts->next);
       -
       -        return img;
       -}
       -
       -void
       -ltk_render_text_segment(
       -        LtkTextSegment *ts,
       -        unsigned int start_x,
       -        unsigned int start_y,
       -        XImage *img,
       -        XColor fg)
       -{
       -        LtkGlyph *glyph = ts->start_glyph;
       -        int x_cur = start_x;
       -        int y_cur = start_y;
       -        int x, y;
       -        double a;
       -        int b;
       -        do {
       -                x = x_cur + glyph->info->xoff + glyph->x_offset;
       -                y = y_cur + glyph->info->yoff - glyph->y_offset;
       -                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;
       -                                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;
       -                        }
       -                }
       -                x_cur += glyph->x_advance;
       -                y_cur -= glyph->y_advance;
       -        } while (glyph = glyph->next);
       -}
       -#endif
   DIR diff --git a/text_common.h b/text_common.h
       t@@ -61,7 +61,6 @@ typedef struct _LtkGlyph {
                int x_abs;
                int y_abs;
                uint32_t cluster; /* index of char in original text - from harfbuzz */
       -        struct _LtkGlyph *next;
        } LtkGlyph;
        
        /* Hash definitions */
       t@@ -116,10 +115,4 @@ uint16_t ltk_get_font(LtkTextManager *tm, char *path);
        
        void ltk_destroy_glyph(LtkGlyph *glyph, khash_t(glyphinfo) *cache);
        
       -/*
       -XImage *ltk_render_text_line(LtkTextLine *tl, Display *dpy, Window window, GC gc, Colormap colormap, XColor fg, XColor bg);
       -
       -void ltk_render_text_segment(LtkTextSegment *ts, unsigned int start_x, unsigned int start_y, XImage *img, XColor fg);
       -*/
       -
        #endif /* _TEXT_COMMON_H_ */