mirror of
https://github.com/jjsullivan5196/wvkbd.git
synced 2025-03-13 02:42:47 +01:00
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.
132 lines
3.5 KiB
C
132 lines
3.5 KiB
C
#include <sys/mman.h>
|
|
#include <unistd.h>
|
|
#include <wayland-client.h>
|
|
|
|
#include "drw.h"
|
|
#include "shm_open.h"
|
|
|
|
void
|
|
drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h, uint32_t s) {
|
|
if (ds->buf) {
|
|
munmap(ds->pool_data, ds->size);
|
|
wl_buffer_destroy(ds->buf);
|
|
ds->buf = NULL;
|
|
}
|
|
|
|
ds->scale = s;
|
|
ds->width = w * s;
|
|
ds->height = h * s;
|
|
|
|
setup_buffer(ds);
|
|
}
|
|
|
|
void
|
|
drwsurf_flip(struct drwsurf *ds) {
|
|
wl_surface_attach(ds->surf, ds->buf, 0, 0);
|
|
wl_surface_commit(ds->surf);
|
|
}
|
|
|
|
void
|
|
drw_draw_text(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
|
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 + 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_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);
|
|
}
|
|
|
|
pango_cairo_show_layout(d->cairo, d->layout);
|
|
cairo_restore(d->cairo);
|
|
}
|
|
|
|
void
|
|
drw_do_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
|
uint32_t w, uint32_t h, bool over) {
|
|
cairo_save(d->cairo);
|
|
|
|
if (over) {
|
|
cairo_set_operator(d->cairo, CAIRO_OPERATOR_OVER);
|
|
} else {
|
|
cairo_set_operator(d->cairo, CAIRO_OPERATOR_SOURCE);
|
|
}
|
|
|
|
cairo_rectangle(d->cairo, x, y, w, h);
|
|
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_fill(d->cairo);
|
|
|
|
cairo_restore(d->cairo);
|
|
}
|
|
|
|
void
|
|
drw_fill_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
|
uint32_t w, uint32_t h) {
|
|
drw_do_rectangle(d, color, x, y, w, h, false);
|
|
}
|
|
|
|
void
|
|
drw_over_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
|
uint32_t w, uint32_t h) {
|
|
drw_do_rectangle(d, color, x, y, w, h, true);
|
|
}
|
|
|
|
uint32_t
|
|
setup_buffer(struct drwsurf *drwsurf) {
|
|
int stride = drwsurf->width * 4;
|
|
drwsurf->size = stride * drwsurf->height;
|
|
|
|
int fd = allocate_shm_file(drwsurf->size);
|
|
if (fd == -1) {
|
|
return 1;
|
|
}
|
|
|
|
drwsurf->pool_data =
|
|
mmap(NULL, drwsurf->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
if (drwsurf->pool_data == MAP_FAILED) {
|
|
close(fd);
|
|
return 1;
|
|
}
|
|
|
|
struct wl_shm_pool *pool =
|
|
wl_shm_create_pool(drwsurf->ctx->shm, fd, drwsurf->size);
|
|
drwsurf->buf = wl_shm_pool_create_buffer(
|
|
pool, 0, drwsurf->width, drwsurf->height, stride, WL_SHM_FORMAT_ARGB8888);
|
|
wl_shm_pool_destroy(pool);
|
|
close(fd);
|
|
|
|
cairo_surface_t *s = cairo_image_surface_create_for_data(
|
|
drwsurf->pool_data, CAIRO_FORMAT_ARGB32, drwsurf->width, drwsurf->height,
|
|
stride);
|
|
|
|
drwsurf->cairo = cairo_create(s);
|
|
cairo_scale(drwsurf->cairo, drwsurf->scale, drwsurf->scale);
|
|
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);
|
|
|
|
return 0;
|
|
}
|