]> git.mdlowis.com Git - proto/labwc.git/commitdiff
icon-loader: update PNG and XPM loaders to use new buffer helper
authorJohn Lindgren <john@jlindgren.net>
Mon, 7 Oct 2024 02:38:03 +0000 (22:38 -0400)
committerJohn Lindgren <john@jlindgren.net>
Mon, 7 Oct 2024 02:38:03 +0000 (22:38 -0400)
include/img/img-png.h
include/img/img-xpm.h
src/icon-loader.c
src/img/img-png.c
src/img/img-xpm.c
src/theme.c

index 1347a53f84ee0df7197dfb04d860f961f675f1b6..2e28c152e8bf902237559731fcd4dc58f823a05b 100644 (file)
@@ -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 */
index 919b810bc7afa313b7dfe3308b2514bf4196dfbc..65d7c2b37a5f0ff64aca8a5ca89f8a0f85f7f55e 100644 (file)
@@ -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 */
index b824f5d53a0523afa2a052f141fd2d1f936d5160..87ae27004fdfbf5426c75c5fe4ea6787168af99c 100644 (file)
@@ -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;
        }
 
index 03357f36701d8c327ffeace88bfa9678d7b68180..cff847269bd5598cdd3edc862c8e32f4d1a0ea0b 100644 (file)
@@ -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);
 }
index d3a98a6ce6a6e6361521ef56aa6d12dc0894228a..3e6598d856714e4ac724b31950dcc28d78e6c341 100644 (file)
@@ -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);
        }
 
index 32bcfa2364c0a10b8d1276261f96a5218fddac34..ac7794a2bdbe1dd8570b0a43ee9cd54155bb673c 100644 (file)
@@ -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