mirror of
https://github.com/labwc/labwc.git
synced 2025-11-01 22:58:47 -04:00
Add buffer_adopt_cairo_surface(), which allows wrapping an existing cairo image surface in a struct lab_data_buffer. This is useful when loading PNGs since most will be loaded as ARGB32 already. Fix a memory leak in the non-ARGB32 PNG case, where we do still need to paint to a new image surface -- we were leaking the original surface. Eliminate an unnecessary temporary image surface in SVG loading and just render the SVG to the image surface held by the lab_data_buffer. I also cleaned up and clarified the buffer API a bit: - Add a pointer to the held cairo_surface_t (so we can still access it if there is no cairo_t). - Remove the free_on_destroy bool (it was always true). - Rename unscaled_width/height to logical_width/height and add an explanatory comment. It was unclear what "unscaled" meant. - Rename buffer_create_wrap() to buffer_create_from_data(). This is laying groundwork for some more icon fixes I am working on (making sure icons are loaded and rendered at the correct scale).
66 lines
1.5 KiB
C
66 lines
1.5 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Copyright (C) Johan Malm 2023
|
|
*/
|
|
#define _POSIX_C_SOURCE 200809L
|
|
#include <cairo.h>
|
|
#include <librsvg/rsvg.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <wlr/util/log.h>
|
|
#include "buffer.h"
|
|
#include "img/img-svg.h"
|
|
#include "common/string-helpers.h"
|
|
#include "labwc.h"
|
|
|
|
void
|
|
img_svg_load(const char *filename, struct lab_data_buffer **buffer,
|
|
int size)
|
|
{
|
|
if (*buffer) {
|
|
wlr_buffer_drop(&(*buffer)->base);
|
|
*buffer = NULL;
|
|
}
|
|
if (string_null_or_empty(filename)) {
|
|
return;
|
|
}
|
|
|
|
GError *err = NULL;
|
|
RsvgRectangle viewport = { .width = size, .height = size };
|
|
RsvgHandle *svg = rsvg_handle_new_from_file(filename, &err);
|
|
if (err) {
|
|
wlr_log(WLR_DEBUG, "error reading svg %s-%s", filename, err->message);
|
|
g_error_free(err);
|
|
/*
|
|
* rsvg_handle_new_from_file() returns NULL if an error occurs,
|
|
* so there is no need to free svg here.
|
|
*/
|
|
return;
|
|
}
|
|
|
|
*buffer = buffer_create_cairo(size, size, 1.0);
|
|
cairo_surface_t *image = (*buffer)->surface;
|
|
cairo_t *cr = (*buffer)->cairo;
|
|
|
|
rsvg_handle_render_document(svg, cr, &viewport, &err);
|
|
if (err) {
|
|
wlr_log(WLR_ERROR, "error rendering svg %s-%s\n", filename, err->message);
|
|
g_error_free(err);
|
|
goto error;
|
|
}
|
|
|
|
if (cairo_surface_status(image)) {
|
|
wlr_log(WLR_ERROR, "error reading svg button '%s'", filename);
|
|
goto error;
|
|
}
|
|
cairo_surface_flush(image);
|
|
|
|
g_object_unref(svg);
|
|
return;
|
|
|
|
error:
|
|
wlr_buffer_drop(&(*buffer)->base);
|
|
*buffer = NULL;
|
|
g_object_unref(svg);
|
|
}
|