From 36f754e6629c30bb1568633c2b0aa6950a8487a7 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sun, 6 Oct 2024 22:38:03 -0400 Subject: [PATCH] icon-loader: update PNG and XPM loaders to use new buffer helper --- include/img/img-png.h | 3 ++- include/img/img-xpm.h | 3 ++- src/icon-loader.c | 4 ++-- src/img/img-png.c | 21 +++------------------ src/img/img-xpm.c | 37 ++++++++++++++++++++----------------- src/theme.c | 9 +++++---- 6 files changed, 34 insertions(+), 43 deletions(-) diff --git a/include/img/img-png.h b/include/img/img-png.h index 1347a53f..2e28c152 100644 --- a/include/img/img-png.h +++ b/include/img/img-png.h @@ -4,6 +4,7 @@ struct lab_data_buffer; -void img_png_load(const char *filename, struct lab_data_buffer **buffer); +void img_png_load(const char *filename, struct lab_data_buffer **buffer, + int size, float scale); #endif /* LABWC_IMG_PNG_H */ diff --git a/include/img/img-xpm.h b/include/img/img-xpm.h index 919b810b..65d7c2b3 100644 --- a/include/img/img-xpm.h +++ b/include/img/img-xpm.h @@ -4,6 +4,7 @@ struct lab_data_buffer; -void img_xpm_load(const char *filename, struct lab_data_buffer **buffer); +void img_xpm_load(const char *filename, struct lab_data_buffer **buffer, + int size, float scale); #endif /* LABWC_IMG_XPM_H */ diff --git a/src/icon-loader.c b/src/icon-loader.c index b824f5d5..87ae2700 100644 --- a/src/icon-loader.c +++ b/src/icon-loader.c @@ -266,7 +266,7 @@ icon_loader_lookup(struct server *server, const char *app_id, int size, switch (ctx.format) { case SFDO_ICON_FILE_FORMAT_PNG: - img_png_load(ctx.path, &icon_buffer); + img_png_load(ctx.path, &icon_buffer, size, scale); break; case SFDO_ICON_FILE_FORMAT_SVG: #if HAVE_RSVG @@ -274,7 +274,7 @@ icon_loader_lookup(struct server *server, const char *app_id, int size, #endif break; case SFDO_ICON_FILE_FORMAT_XPM: - img_xpm_load(ctx.path, &icon_buffer); + img_xpm_load(ctx.path, &icon_buffer, size, scale); break; } diff --git a/src/img/img-png.c b/src/img/img-png.c index 03357f36..cff84726 100644 --- a/src/img/img-png.c +++ b/src/img/img-png.c @@ -43,7 +43,8 @@ ispng(const char *filename) #undef PNG_BYTES_TO_CHECK void -img_png_load(const char *filename, struct lab_data_buffer **buffer) +img_png_load(const char *filename, struct lab_data_buffer **buffer, int size, + float scale) { if (*buffer) { wlr_buffer_drop(&(*buffer)->base); @@ -62,22 +63,6 @@ img_png_load(const char *filename, struct lab_data_buffer **buffer) cairo_surface_destroy(image); return; } - cairo_surface_flush(image); - if (cairo_image_surface_get_format(image) == CAIRO_FORMAT_ARGB32) { - /* we can wrap ARGB32 image surfaces directly */ - *buffer = buffer_adopt_cairo_surface(image); - return; - } - - /* convert to ARGB32 by painting to a new surface */ - uint32_t w = cairo_image_surface_get_width(image); - uint32_t h = cairo_image_surface_get_height(image); - *buffer = buffer_create_cairo(w, h, 1); - cairo_t *cairo = (*buffer)->cairo; - cairo_set_source_surface(cairo, image, 0, 0); - cairo_paint(cairo); - cairo_surface_flush((*buffer)->surface); - /* destroy original surface */ - cairo_surface_destroy(image); + *buffer = buffer_convert_cairo_surface_for_icon(image, size, scale); } diff --git a/src/img/img-xpm.c b/src/img/img-xpm.c index d3a98a6c..3e6598d8 100644 --- a/src/img/img-xpm.c +++ b/src/img/img-xpm.c @@ -286,9 +286,8 @@ file_buffer(enum buf_op op, struct file_handle *h) return NULL; } -/* This function does all the work. */ -static struct lab_data_buffer * -pixbuf_create_from_xpm(struct file_handle *handle) +static cairo_surface_t * +xpm_load_to_surface(struct file_handle *handle) { const char *buffer = file_buffer(op_header, handle); if (!buffer) { @@ -332,7 +331,7 @@ pixbuf_create_from_xpm(struct file_handle *handle) char *name_buf = xzalloc(n_col * (cpp + 1)); struct xpm_color *colors = znew_n(struct xpm_color, n_col); - uint32_t *data = znew_n(uint32_t, w * h); + cairo_surface_t *surface = NULL; struct xpm_color *fallbackcolor = NULL; char pixel_str[32]; /* cpp < 32 */ @@ -357,14 +356,20 @@ pixbuf_create_from_xpm(struct file_handle *handle) } } + surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); + uint32_t *data = (uint32_t *)cairo_image_surface_get_data(surface); + int stride = cairo_image_surface_get_stride(surface) / sizeof(uint32_t); + for (int ycnt = 0; ycnt < h; ycnt++) { - uint32_t *pixtmp = data + w * ycnt; + uint32_t *pixtmp = data + stride * ycnt; int wbytes = w * cpp; buffer = file_buffer(op_body, handle); if (!buffer || (strlen(buffer) < (size_t)wbytes)) { /* Advertised width doesn't match pixels */ wlr_log(WLR_DEBUG, "Dimensions do not match data"); + cairo_surface_destroy(surface); + surface = NULL; goto out; } @@ -382,24 +387,19 @@ pixbuf_create_from_xpm(struct file_handle *handle) *pixtmp++ = color->argb; } } - - g_hash_table_destroy(color_hash); - free(colors); - free(name_buf); - - return buffer_create_from_data(data, w, h, 4 * w); + /* let cairo know pixel data has been modified */ + cairo_surface_mark_dirty(surface); out: g_hash_table_destroy(color_hash); free(colors); free(name_buf); - free(data); - - return NULL; + return surface; } void -img_xpm_load(const char *filename, struct lab_data_buffer **buffer) +img_xpm_load(const char *filename, struct lab_data_buffer **buffer, int size, + float scale) { if (*buffer) { wlr_buffer_drop(&(*buffer)->base); @@ -413,8 +413,11 @@ img_xpm_load(const char *filename, struct lab_data_buffer **buffer) return; } - *buffer = pixbuf_create_from_xpm(&h); - if (!(*buffer)) { + cairo_surface_t *surface = xpm_load_to_surface(&h); + if (surface) { + *buffer = buffer_convert_cairo_surface_for_icon(surface, size, + scale); + } else { wlr_log(WLR_ERROR, "error loading '%s'", filename); } diff --git a/src/theme.c b/src/theme.c index 32bcfa23..ac7794a2 100644 --- a/src/theme.c +++ b/src/theme.c @@ -246,19 +246,20 @@ load_button(struct theme *theme, struct button *b, int active) zdrop(buffer); + int size = theme->title_height - 2 * theme->padding_height; + float scale = 1; /* TODO: account for output scale */ + /* PNG */ get_button_filename(filename, sizeof(filename), b->name, active ? "-active.png" : "-inactive.png"); - img_png_load(filename, buffer); + img_png_load(filename, buffer, size, scale); #if HAVE_RSVG /* SVG */ if (!*buffer) { - int size = theme->title_height - 2 * theme->padding_height; get_button_filename(filename, sizeof(filename), b->name, active ? "-active.svg" : "-inactive.svg"); - /* TODO: account for output scale */ - img_svg_load(filename, buffer, size, 1); + img_svg_load(filename, buffer, size, scale); } #endif -- 2.52.0