commit d6e2f851b663e5db6957c3fb5c41f595c139c3c6
parent 288e467a6083a547a3996e69b6ba0ea1d430e70b
Author: lumidify <nobody@lumidify.org>
Date: Wed, 27 May 2020 21:19:10 +0200
Somewhat improve drawing
Diffstat:
6 files changed, 31 insertions(+), 143 deletions(-)
diff --git a/NOTES b/NOTES
@@ -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
diff --git a/ltk.c b/ltk.c
@@ -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;
+ }
}
}
@@ -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;
@@ -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)
@@ -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;
@@ -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;
}
diff --git a/ltk.h b/ltk.h
@@ -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;
@@ -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);
@@ -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
diff --git a/text_buffer.c b/text_buffer.c
@@ -21,7 +21,6 @@
* SOFTWARE.
*/
-#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -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;
@@ -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 *
@@ -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;
@@ -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;
}
@@ -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;
@@ -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;
@@ -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
@@ -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;
@@ -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;
@@ -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 */
diff --git a/text_common.c b/text_common.c
@@ -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
diff --git a/text_common.h b/text_common.h
@@ -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 */
@@ -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_ */