commit 6dd04b169616da62128fa4e952b005d6139c9100
parent 212c90119c1d23d23f18fc5ed5c5ab5af494b79f
Author: lumidify <nobody@lumidify.org>
Date: Thu, 21 May 2020 20:41:43 +0200
Fix infinite loop in text wrapping; standardize some function names
Diffstat:
7 files changed, 44 insertions(+), 40 deletions(-)
diff --git a/button.c b/button.c
@@ -38,8 +38,8 @@
extern Ltk *ltk_global;
-void ltk_button_ini_handler(LtkTheme *theme, const char *prop, const char *value)
-{
+void
+ltk_button_ini_handler(LtkTheme *theme, const char *prop, const char *value) {
if (theme->button == NULL) {
theme->button = malloc(sizeof(LtkButtonTheme));
}
@@ -76,8 +76,8 @@ void ltk_button_ini_handler(LtkTheme *theme, const char *prop, const char *value
}
}
-void ltk_draw_button(LtkButton *button)
-{
+void
+ltk_button_draw(LtkButton *button) {
LtkButtonTheme *theme = ltk_global->theme->button;
LtkWindow *window = button->widget.window;
LtkRect rect = button->widget.rect;
@@ -150,15 +150,15 @@ void ltk_draw_button(LtkButton *button)
XPutImage(ltk_global->display, window->xwindow, window->gc, img, 0, 0, text_x, text_y, button->tl->w, button->tl->h);
}
-LtkButton *ltk_create_button(LtkWindow *window, const char *text, void (*callback) (void *, XEvent, void *), void *data)
-{
+LtkButton *
+ltk_button_create(LtkWindow *window, const char *text, void (*callback) (void *, XEvent, void *), void *data) {
LtkButton *button = malloc(sizeof(LtkButton));
if (button == NULL) {
ltk_fatal("ERROR: Unable to allocate memory for LtkButton.\n");
}
- ltk_fill_widget_defaults(&button->widget, window, <k_draw_button, <k_destroy_button, 1);
+ ltk_fill_widget_defaults(&button->widget, window, <k_button_draw, <k_button_destroy, 1);
button->widget.mouse_release = <k_button_mouse_release;
button->callback = callback;
@@ -179,8 +179,8 @@ LtkButton *ltk_create_button(LtkWindow *window, const char *text, void (*callbac
return button;
}
-void ltk_destroy_button(LtkButton *button)
-{
+void
+ltk_button_destroy(LtkButton *button) {
if (!button) {
(void)printf("WARNING: Tried to destroy NULL button.\n");
}
@@ -195,7 +195,8 @@ void ltk_destroy_button(LtkButton *button)
/* FIXME: is the fixme below supposed to be for the function above? */
/* FIXME: ungrid button if gridded */
-void ltk_button_mouse_release(LtkButton *button, XEvent event) {
+void
+ltk_button_mouse_release(LtkButton *button, XEvent event) {
if (button->widget.state == LTK_HOVERACTIVE && button->callback) {
button->callback(button, event, button->data);
}
diff --git a/button.h b/button.h
@@ -61,11 +61,11 @@ typedef struct LtkButtonTheme {
XColor fill_disabled;
} LtkButtonTheme;
-void ltk_draw_button(LtkButton *button);
+void ltk_button_draw(LtkButton *button);
-LtkButton *ltk_create_button(LtkWindow * window, const char *text, void (*callback) (void *, XEvent, void *), void *data);
+LtkButton *ltk_button_create(LtkWindow * window, const char *text, void (*callback) (void *, XEvent, void *), void *data);
-void ltk_destroy_button(LtkButton *button);
+void ltk_button_destroy(LtkButton *button);
void ltk_button_mouse_release(LtkButton *button, XEvent event);
diff --git a/ltk.c b/ltk.c
@@ -185,13 +185,15 @@ void ltk_window_other_event(void *widget, XEvent event)
unsigned int w, h;
w = event.xconfigure.width;
h = event.xconfigure.height;
+ int orig_w = window->rect.w;
+ int orig_h = window->rect.h;
if (ptr && ptr->resize
- && (window->rect.w != w || window->rect.h != h)) {
+ && (orig_w != w || orig_h != h)) {
window->rect.w = w;
window->rect.h = h;
ptr->rect.w = w;
ptr->rect.h = h;
- ptr->resize(ptr);
+ ptr->resize(ptr, orig_w, orig_h);
ltk_redraw_window(window);
}
}
diff --git a/test1.c b/test1.c
@@ -21,7 +21,6 @@ int main(int argc, char *argv[])
{
ltk_init("themes/default.ini");
LtkWindow *window1 = ltk_create_window("Cool Window!", 0, 0, 500, 500);
-/* LtkWindow *window2 = ltk_create_window("Cool Window!", 0, 0, 500, 500);*/
LtkGrid *grid1 = ltk_create_grid(window1, 2, 2);
window1->root_widget = grid1;
ltk_set_row_weight(grid1, 0, 1);
@@ -29,18 +28,14 @@ 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, NULL);
+ LtkButton *button1 = ltk_button_create(window1, "I'm a button!", &bob1, NULL);
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, NULL);
+ LtkButton *button2 = ltk_button_create(window1, "I'm a button!", NULL, 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, "پَیدایش", NULL);
- LtkTextEdit *edit = ltk_create_text_edit(window1, "ہمارے بارے میں blabla bla");
- LtkButton *button4 = ltk_create_button(window1, "ہمارے بارے میں blablabla", &bob3, edit);
+ LtkTextEdit *edit = ltk_text_edit_create(window1, "ہمارے بارے میں blabla bla");
+ LtkButton *button4 = ltk_button_create(window1, "ہمارے بارے میں blablabla", &bob3, edit);
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();
diff --git a/text_buffer.c b/text_buffer.c
@@ -77,6 +77,7 @@ ltk_text_line_cleanup_soft_lines(struct ltk_array_line *soft_lines, int old_len)
ltk_array_resize_line(soft_lines, soft_lines->len);
}
+/* FIXME: this is a few pixels off! */
void
ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) {
struct timeval t1, t2;
@@ -129,9 +130,11 @@ ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) {
/* FIXME: fix behavior when line isn't wide enough for single char
(currently causes infinite loop) */
for (int j = i; j < cur->num_glyphs; j++) {
- if (cur->glyphs[j].cluster != glyph->cluster || j == cur->num_glyphs - 1) {
+ if (cur->glyphs[j].cluster != glyph->cluster ||
+ j == cur->num_glyphs - 1 || sl->len == 0) {
if (j == cur->num_glyphs - 1 &&
- cur->glyphs[j].cluster == glyph->cluster) {
+ cur->glyphs[j].cluster == glyph->cluster &&
+ sl->len > 0) {
i = j;
last_linebreak = cur_start;
} else {
@@ -172,8 +175,11 @@ ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) {
int cur_w = sl->w + glyph->x_abs + glyph->info->w - cur_start;
if (cur_w > max_width) {
for (int j = i; j >= 0; j--) {
- if (cur->glyphs[j].cluster != glyph->cluster || j == 0) {
- if (j == 0 && cur->glyphs[j].cluster == glyph->cluster) {
+ if (cur->glyphs[j].cluster != glyph->cluster ||
+ j == 0 || sl->len == 0) {
+ if (j == 0 &&
+ cur->glyphs[j].cluster == glyph->cluster &&
+ sl->len > 0) {
i = j;
last_linebreak = cur_start;
} else {
@@ -252,7 +258,7 @@ ltk_soft_line_draw_glyph(LtkGlyph *glyph, XImage *img, struct ltk_soft_line *sl,
int b;
for (int i = 0; i < glyph->info->h; i++) {
for (int j = 0; j < glyph->info->w; j++) {
- if (y + i >= img->height || x + j >= img->width || y < 0 || x < 0)
+ if (y + i >= img->height || x + j >= img->width || y + i < 0 || x + i < 0)
continue;
b = (y + i) * img->bytes_per_line + (x + j) * 4;
a = glyph->info->alphamap[i * glyph->info->w + j] / 255.0;
@@ -263,6 +269,7 @@ ltk_soft_line_draw_glyph(LtkGlyph *glyph, XImage *img, struct ltk_soft_line *sl,
}
}
+/* FIXME: the glyph drawing function sometimes receives negative x positions */
/* FIXME: Fix memory leaks... */
XImage *
ltk_text_line_render(
diff --git a/text_edit.c b/text_edit.c
@@ -40,14 +40,14 @@
extern Ltk *ltk_global;
void
-ltk_draw_text_edit(LtkTextEdit *te) {
+ltk_text_edit_draw(LtkTextEdit *te) {
if (!te->img)
ltk_text_edit_resize(te, 0, 0);
LtkRect rect = te->widget.rect;
LtkWindow *window = te->widget.window;
int x = rect.x;
if (te->tl->dir == HB_DIRECTION_RTL)
- x += rect.w - te->tl->w_wrapped;
+ x += rect.w - te->img->width;
XSetForeground(ltk_global->display, window->gc, ltk_global->theme->window->bg.pixel);
XFillRectangle(ltk_global->display, window->xwindow, window->gc, rect.x, rect.y, rect.w, rect.h);
XPutImage(
@@ -64,7 +64,7 @@ ltk_draw_text_edit(LtkTextEdit *te) {
void
ltk_text_edit_resize(LtkTextEdit *te, int orig_w, int orig_h) {
if (te->tl->soft_lines->len == 1 &&
- te->widget.rect.w >= te->tl->w_wrapped && orig_w >= te->tl->w_wrapped)
+ te->widget.rect.w >= te->img->width && orig_w >= te->img->width)
return;
XColor fg = ltk_global->theme->window->fg;
XColor bg = ltk_global->theme->window->bg;
@@ -91,12 +91,12 @@ ltk_text_edit_tmp(LtkTextEdit *te, XEvent event) {
#endif
LtkTextEdit *
-ltk_create_text_edit(LtkWindow *window, const char *text) {
+ltk_text_edit_create(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, <k_draw_text_edit, <k_destroy_text_edit, 1);
+ ltk_fill_widget_defaults(&te->widget, window, <k_text_edit_draw, <k_text_edit_destroy, 1);
/*te->widget.mouse_press = <k_text_edit_tmp;*/
te->widget.resize = <k_text_edit_resize;
te->tl = ltk_text_line_create(20);
@@ -110,10 +110,10 @@ ltk_text_edit_insert_text(LtkTextEdit *te, const char *text) {
ltk_text_line_insert_utf8(te->tl, 0, text);
ltk_text_edit_resize(te, 0, 0);
/* FIXME: Need to "queue redraw" for whole window */
- ltk_draw_text_edit(te);
+ ltk_text_edit_draw(te);
}
-void ltk_destroy_text_edit(LtkTextEdit *te) {
+void ltk_text_edit_destroy(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
@@ -30,11 +30,10 @@ typedef struct {
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_draw(LtkTextEdit *te);
+LtkTextEdit *ltk_text_edit_create(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);
+void ltk_text_edit_destroy(LtkTextEdit *te);
#endif /* _LTK_TEXT_EDIT_H_ */