From c45446a794399b96894ecbf07331c7321fa4ed4c Mon Sep 17 00:00:00 2001 From: Willow Barraco Date: Thu, 31 Aug 2023 15:23:11 +0200 Subject: [PATCH] Do not write texts outside of keys This is a bit hacky. The main problem is that there is no way to tell cairo to limit the width. It will wrap text accordingly to width and height, it will add ellipsizes if it overlow the box, but if a word width is larger than the box width, it will write it. To avoid that, I make sure we don't go too much to the left, and I redraw the background at the right of the keys. This is not visible cause we damage track correctly the updated buffer coordinates. I also moved the damage tracking from do_rectangle and draw_text to higher draw_key and draw_layout. --- drw.c | 26 ++++++++++++++++---------- drw.h | 2 +- keyboard.c | 12 +++++++++++- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/drw.c b/drw.c index 6ea904e..cb8ebd1 100644 --- a/drw.c +++ b/drw.c @@ -28,26 +28,32 @@ drwsurf_flip(struct drwsurf *ds) { void drw_draw_text(struct drwsurf *d, Color color, uint32_t x, uint32_t y, - uint32_t w, uint32_t h, const char *label) { + uint32_t w, uint32_t h, uint32_t b, const char *label) { cairo_save(d->cairo); cairo_set_source_rgba( d->cairo, color.bgra[2] / (double)255, color.bgra[1] / (double)255, - color.bgra[0] / (double)255, color.bgra[3] / (double)255); - cairo_move_to(d->cairo, x + (double)w / 2.0, y + (double)h / 2.0); + color.bgra[0] / (double)255, color.bgra[3] / (double)255 + ); + cairo_move_to(d->cairo, x + w / 2, y + h / 2); pango_layout_set_text(d->layout, label, -1); + pango_layout_set_width(d->layout, (w - (b*2)) * PANGO_SCALE); + pango_layout_set_height(d->layout, (h - (b*2)) * PANGO_SCALE); int width, height; - pango_layout_get_size(d->layout, &width, &height); + pango_layout_get_pixel_size(d->layout, &width, &height); + + // if a word is too long, cairo let it, and ignore our width + if (width < (w - (b*2))) { + cairo_rel_move_to(d->cairo, - width / 2, - height / 2); + } else { + cairo_rel_move_to(d->cairo, - w / 2 + b, - height / 2); + } - cairo_rel_move_to(d->cairo, -((double)width / PANGO_SCALE) / 2, - -((double)height / PANGO_SCALE) / 2); pango_cairo_show_layout(d->cairo, d->layout); cairo_restore(d->cairo); - - wl_surface_damage(d->surf, x, y, w, h); } void @@ -68,8 +74,6 @@ drw_do_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y, cairo_fill(d->cairo); cairo_restore(d->cairo); - - wl_surface_damage(d->surf, x, y, w, h); } void @@ -117,6 +121,8 @@ setup_buffer(struct drwsurf *drwsurf) { drwsurf->layout = pango_cairo_create_layout(drwsurf->cairo); pango_layout_set_font_description(drwsurf->layout, drwsurf->ctx->font_description); + pango_layout_set_ellipsize(drwsurf->layout, PANGO_ELLIPSIZE_END); + pango_layout_set_auto_dir(drwsurf->layout, false); cairo_save(drwsurf->cairo); wl_surface_set_buffer_scale(drwsurf->surf, drwsurf->scale); diff --git a/drw.h b/drw.h index c1139f4..1ed6b19 100644 --- a/drw.h +++ b/drw.h @@ -38,7 +38,7 @@ void drw_over_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y, uint32_t w, uint32_t h); void drw_draw_text(struct drwsurf *d, Color color, uint32_t x, uint32_t y, - uint32_t w, uint32_t h, const char *label); + uint32_t w, uint32_t h, uint32_t b, const char *label); uint32_t setup_buffer(struct drwsurf *drwsurf); diff --git a/keyboard.c b/keyboard.c index 526fbe8..24ba335 100644 --- a/keyboard.c +++ b/keyboard.c @@ -504,6 +504,7 @@ kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type) { fprintf(stderr, "Draw key +%d+%d %dx%d -> %s\n", k->x, k->y, k->w, k->h, label); struct clr_scheme *scheme = (k->scheme == 0) ? &(kb->scheme) : &(kb->scheme1); + switch (type) { case Unpress: draw_inset(d, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, scheme->fg); @@ -515,7 +516,15 @@ kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type) { draw_over_inset(d, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, scheme->swipe); break; } - drw_draw_text(d, scheme->text, k->x, k->y, k->w, k->h, label); + + drw_draw_text(d, scheme->text, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, label); + + // cleanup cairo mess right side if words too long + uint32_t right_part_x = k->x + k->w - 2 * KBD_KEY_BORDER; + drw_do_rectangle(d, kb->scheme.bg, right_part_x, k->y, + kb->w - right_part_x, kb->h, false); + + wl_surface_damage(d->surf, k->x, k->y, k->w, k->h); } void @@ -540,6 +549,7 @@ kbd_draw_layout(struct kbd *kb) { } next_key++; } + wl_surface_damage(d->surf, 0, 0, kb->w, kb->h); } void