ltkx

GUI toolkit for X11 (WIP)
git clone git://lumidify.org/ltkx.git
Log | Files | Refs | README | LICENSE

commit 212c90119c1d23d23f18fc5ed5c5ab5af494b79f
parent 201782e6c6df60ab9082852042d210b5d809f797
Author: lumidify <nobody@lumidify.org>
Date:   Thu, 21 May 2020 19:52:48 +0200

Change text_line rendering to return image

Diffstat:
Mbutton.c | 9++-------
Mbutton.h | 1+
Mtext_buffer.c | 29++++++++++++++---------------
Mtext_buffer.h | 5++---
Mtext_edit.c | 12++++++++----
Mtext_edit.h | 3++-
Mthemes/default.ini | 2+-
7 files changed, 30 insertions(+), 31 deletions(-)

diff --git a/button.c b/button.c @@ -124,12 +124,7 @@ void ltk_draw_button(LtkButton *button) XSetLineAttributes(ltk_global->display, window->gc, bw, LineSolid, CapButt, JoinMiter); XDrawRectangle(ltk_global->display, window->xwindow, window->gc, rect.x + bw / 2, rect.y + bw / 2, rect.w - bw, rect.h - bw); if (!img) { - /* FIXME: make this a bit nicer - text_line is made for text_buffer, but - it really doesn't make much sense here to store the image in text_line */ - ltk_text_line_render(button->tl, ltk_global->display, window->xwindow, window->gc, ltk_global->colormap, theme->text_color, fill); - img = button->tl->img; - /* set to NULL so it isn't freed on next call to render */ - button->tl->img = NULL; + img = ltk_text_line_render(button->tl, ltk_global->display, window->xwindow, window->gc, ltk_global->colormap, theme->text_color, fill); /* FIXME: any nicer way to do this? */ switch (button->widget.state) { case LTK_NORMAL: @@ -169,7 +164,7 @@ LtkButton *ltk_create_button(LtkWindow *window, const char *text, void (*callbac button->callback = callback; button->data = data; LtkTheme *theme = ltk_global->theme; - button->tl = ltk_text_line_create(); + button->tl = ltk_text_line_create(theme->button->font_size); /* FIXME: support font size */ ltk_text_line_insert_utf8(button->tl, 0, text); ltk_text_line_wrap(button->tl, -1); diff --git a/button.h b/button.h @@ -40,6 +40,7 @@ typedef struct { typedef struct LtkButtonTheme { int border_width; + /* FIXME: this should actually be uint16_t */ int font_size; XColor text_color; int pad; diff --git a/text_buffer.c b/text_buffer.c @@ -264,7 +264,7 @@ ltk_soft_line_draw_glyph(LtkGlyph *glyph, XImage *img, struct ltk_soft_line *sl, } /* FIXME: Fix memory leaks... */ -void +XImage * ltk_text_line_render( struct ltk_text_line *tl, Display *dpy, @@ -283,9 +283,8 @@ ltk_text_line_render( XWindowAttributes attrs; XGetWindowAttributes(dpy, window, &attrs); int depth = attrs.depth; - /* FIXME: if tl->img has same dimensions, just clear it */ - if (tl->img) XDestroyImage(tl->img); - tl->img = ltk_create_ximage(dpy, tl->w_wrapped, tl->h_wrapped, depth, bg); + /* FIXME: pass old image; if it has same dimensions, just clear it */ + XImage *img = ltk_create_ximage(dpy, tl->w_wrapped, tl->h_wrapped, depth, bg); for (int i = 0; i < tl->soft_lines->len; i++) { struct ltk_soft_line *sl = tl->soft_lines->buf[i]; @@ -314,15 +313,15 @@ ltk_text_line_render( if (par_is_rtl) { for (int j = start_index; j >= 0 && cur_len < sl->len; j--) { cur_len++; - int x = cur_border - (local_border - cur->glyphs[j].x_abs) + tl->img->width - sl->w; - ltk_soft_line_draw_glyph(&cur->glyphs[j], tl->img, sl, x, cur->glyphs[j].y_abs + tl->h * i, fg); + int x = cur_border - (local_border - cur->glyphs[j].x_abs) + img->width - sl->w; + ltk_soft_line_draw_glyph(&cur->glyphs[j], img, sl, x, cur->glyphs[j].y_abs + tl->h * i, fg); } cur_border -= local_border - cur->glyphs[end_index].x_abs; } else { for (int j = end_index; j <= start_index && cur_len < sl->len; j++) { cur_len++; int x = cur_border + (cur->glyphs[j].x_abs - cur->glyphs[end_index].x_abs); - ltk_soft_line_draw_glyph(&cur->glyphs[j], tl->img, sl, x, cur->glyphs[j].y_abs + tl->h * i, fg); + ltk_soft_line_draw_glyph(&cur->glyphs[j], img, sl, x, cur->glyphs[j].y_abs + tl->h * i, fg); } cur_border += local_border - cur->glyphs[end_index].x_abs; } @@ -337,15 +336,15 @@ ltk_text_line_render( if (par_is_rtl) { for (int j = end_index; j >= start_index && cur_len < sl->len; j--) { cur_len++; - int x = cur_border - (cur->glyphs[end_index].x_abs + cur->glyphs[end_index].x_advance - cur->glyphs[j].x_abs) + tl->img->width - sl->w; - ltk_soft_line_draw_glyph(&cur->glyphs[j], tl->img, sl, x, cur->glyphs[j].y_abs + tl->h * i, fg); + int x = cur_border - (cur->glyphs[end_index].x_abs + cur->glyphs[end_index].x_advance - cur->glyphs[j].x_abs) + img->width - sl->w; + ltk_soft_line_draw_glyph(&cur->glyphs[j], img, sl, x, cur->glyphs[j].y_abs + tl->h * i, fg); } cur_border -= cur->glyphs[cur->num_glyphs - 1].x_abs + cur->glyphs[cur->num_glyphs - 1].x_advance - local_border; } else { for (int j = start_index; j < cur->num_glyphs && cur_len < sl->len; j++) { cur_len++; int x = cur_border + (cur->glyphs[j].x_abs - local_border); - ltk_soft_line_draw_glyph(&cur->glyphs[j], tl->img, sl, x, cur->glyphs[j].y_abs + tl->h * i, fg); + ltk_soft_line_draw_glyph(&cur->glyphs[j], img, sl, x, cur->glyphs[j].y_abs + tl->h * i, fg); } cur_border += cur->glyphs[cur->num_glyphs - 1].x_abs + cur->glyphs[cur->num_glyphs - 1].x_advance - local_border; } @@ -357,6 +356,7 @@ ltk_text_line_render( } gettimeofday(&t2, NULL); printf("render2: %d, %d, diff: %d\n", t2.tv_sec, t2.tv_usec, t2.tv_usec - t1.tv_usec); + return img; } uint32_t @@ -859,7 +859,7 @@ ltk_text_line_insert_utf8(struct ltk_text_line *tl, size_t index, char *text) { } struct ltk_text_line * -ltk_text_line_create(void) { +ltk_text_line_create(uint16_t font_size) { struct ltk_text_line *line = malloc(sizeof(struct ltk_text_line)); if (!line) goto error; line->log_buf = ltk_array_create_uint32(4); @@ -873,10 +873,9 @@ ltk_text_line_create(void) { line->next = NULL; line->len = 0; line->w_wrapped = line->h_wrapped = 0; - line->img = NULL; + line->font_size = font_size; /* FIXME */ - line->font_size = 20; - line->line_gap = 5; + line->line_gap = 0; return line; error: (void)fprintf(stderr, "No memory left while creating text line\n"); @@ -941,7 +940,7 @@ ltk_text_buffer_create(void) { (void)fprintf(stderr, "No memory while creating text buffer\n"); exit(1); } - buf->head = ltk_text_line_create(); + buf->head = ltk_text_line_create(20); buf->cur_line = buf->head; buf->cursor_pos = 0; buf->line_gap = 0; diff --git a/text_buffer.h b/text_buffer.h @@ -85,7 +85,6 @@ struct ltk_text_line { int w_wrapped; int h_wrapped; unsigned int line_gap; - XImage *img; }; struct ltk_text_buffer { @@ -96,12 +95,12 @@ struct ltk_text_buffer { }; void ltk_soft_line_destroy(struct ltk_soft_line *sl); -void ltk_text_line_render(struct ltk_text_line *tl, +XImage *ltk_text_line_render(struct ltk_text_line *tl, Display *dpy, Window window, GC gc, Colormap colormap, XColor fg, XColor bg); uint32_t ltk_soft_line_get_index_from_pos(int x, struct ltk_text_line *tl, struct ltk_soft_line *sl, int *found_pos); void ltk_text_line_insert_utf32(struct ltk_text_line *tl, size_t index, uint32_t *text, size_t len); void ltk_text_line_insert_utf8(struct ltk_text_line *tl, size_t index, char *text); -struct ltk_text_line *ltk_text_line_create(void); +struct ltk_text_line *ltk_text_line_create(uint16_t font_size); void ltk_text_line_destroy(struct ltk_text_line *tl); #endif /* _TEXT_BUFFER_H_ */ diff --git a/text_edit.c b/text_edit.c @@ -41,7 +41,8 @@ extern Ltk *ltk_global; void ltk_draw_text_edit(LtkTextEdit *te) { - /* FIXME: this requires img to be non-null */ + if (!te->img) + ltk_text_edit_resize(te, 0, 0); LtkRect rect = te->widget.rect; LtkWindow *window = te->widget.window; int x = rect.x; @@ -53,7 +54,7 @@ ltk_draw_text_edit(LtkTextEdit *te) { ltk_global->display, window->xwindow, window->gc, - te->tl->img, + te->img, 0, 0, x, rect.y, te->tl->w_wrapped, te->tl->h_wrapped @@ -69,7 +70,8 @@ ltk_text_edit_resize(LtkTextEdit *te, int orig_w, int orig_h) { XColor bg = ltk_global->theme->window->bg; LtkWindow *window = te->widget.window; ltk_text_line_wrap(te->tl, te->widget.rect.w); - ltk_text_line_render(te->tl, ltk_global->display, window->xwindow, window->gc, ltk_global->colormap, fg, bg); + if (te->img) XDestroyImage(te->img); + te->img = ltk_text_line_render(te->tl, ltk_global->display, window->xwindow, window->gc, ltk_global->colormap, fg, bg); } #if 0 @@ -93,10 +95,11 @@ 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"); + te->img = NULL; ltk_fill_widget_defaults(&te->widget, window, &ltk_draw_text_edit, &ltk_destroy_text_edit, 1); /*te->widget.mouse_press = &ltk_text_edit_tmp;*/ te->widget.resize = &ltk_text_edit_resize; - te->tl = ltk_text_line_create(); + te->tl = ltk_text_line_create(20); ltk_text_edit_insert_text(te, text); return te; } @@ -112,5 +115,6 @@ ltk_text_edit_insert_text(LtkTextEdit *te, const char *text) { void ltk_destroy_text_edit(LtkTextEdit *te) { ltk_text_line_destroy(te->tl); + if (te->img) XDestroyImage(te->img); free(te); } diff --git a/text_edit.h b/text_edit.h @@ -26,13 +26,14 @@ typedef struct { LtkWidget widget; - uint32_t cursor; struct ltk_text_line *tl; + XImage *img; } LtkTextEdit; /* 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_resize(LtkTextEdit *te, int orig_w, int orig_h); void ltk_text_edit_insert_text(LtkTextEdit *te, const char *text); void ltk_destroy_text_edit(LtkTextEdit *te); diff --git a/themes/default.ini b/themes/default.ini @@ -6,7 +6,7 @@ font = Awami Nastaliq [button] border_width = 2 -font_size = 30 +font_size = 20 text_color = #FFFFFF pad = 5 border = #339999