From 82b0235acacc830cdce24655c75c465f1301fffe Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Fri, 30 May 2025 20:55:31 +0900 Subject: [PATCH] buffer: add buffer_resize() --- include/buffer.h | 7 +++++++ src/buffer.c | 35 +++++++++++++++++++++++++++++++++++ src/img/img.c | 42 ++---------------------------------------- 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/include/buffer.h b/include/buffer.h index c034a874..a756a7b5 100644 --- a/include/buffer.h +++ b/include/buffer.h @@ -70,4 +70,11 @@ struct lab_data_buffer *buffer_create_cairo(uint32_t logical_width, struct lab_data_buffer *buffer_create_from_data(void *pixel_data, uint32_t width, uint32_t height, uint32_t stride); +/* + * Resize a buffer to the given size. The source buffer is rendered at the + * center of the output buffer and shrunk if it overflows from the output buffer. + */ +struct lab_data_buffer *buffer_resize(struct lab_data_buffer *src_buffer, + int width, int height, double scale); + #endif /* LABWC_BUFFER_H */ diff --git a/src/buffer.c b/src/buffer.c index 1badaf6e..08560116 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -29,6 +29,7 @@ #include #include #include "buffer.h" +#include "common/box.h" #include "common/mem.h" static const struct wlr_buffer_impl data_buffer_impl; @@ -146,3 +147,37 @@ buffer_create_from_data(void *pixel_data, uint32_t width, uint32_t height, buffer->surface_owns_data = false; return buffer; } + +struct lab_data_buffer * +buffer_resize(struct lab_data_buffer *src_buffer, int width, int height, + double scale) +{ + assert(src_buffer); + cairo_surface_t *surface = src_buffer->surface; + + int src_w = cairo_image_surface_get_width(surface); + int src_h = cairo_image_surface_get_height(surface); + + struct lab_data_buffer *buffer = + buffer_create_cairo(width, height, scale); + cairo_t *cairo = cairo_create(buffer->surface); + + struct wlr_box container = { + .width = width, + .height = height, + }; + + struct wlr_box dst_box = box_fit_within(src_w, src_h, &container); + double scene_scale = (double)dst_box.width / (double)src_w; + cairo_translate(cairo, dst_box.x, dst_box.y); + cairo_scale(cairo, scene_scale, scene_scale); + cairo_set_source_surface(cairo, surface, 0, 0); + cairo_pattern_set_filter(cairo_get_source(cairo), CAIRO_FILTER_GOOD); + cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); + cairo_paint(cairo); + + cairo_surface_flush(buffer->surface); + cairo_destroy(cairo); + + return buffer; +} diff --git a/src/img/img.c b/src/img/img.c index 5e4b473f..03b9130a 100644 --- a/src/img/img.c +++ b/src/img/img.c @@ -112,42 +112,6 @@ lab_img_add_modifier(struct lab_img *img, lab_img_modifier_func_t modifier) *mod = modifier; } -/* - * Takes a source surface from PNG/XBM/XPM file and output a buffer for the - * given size. The source surface is placed at the center of the output buffer - * and shrunk if it overflows from the output buffer. - */ -static struct lab_data_buffer * -render_cairo_surface(cairo_surface_t *surface, int width, int height, - double scale) -{ - assert(surface); - int src_w = cairo_image_surface_get_width(surface); - int src_h = cairo_image_surface_get_height(surface); - - struct lab_data_buffer *buffer = - buffer_create_cairo(width, height, scale); - cairo_t *cairo = cairo_create(buffer->surface); - - struct wlr_box container = { - .width = width, - .height = height, - }; - - struct wlr_box dst_box = box_fit_within(src_w, src_h, &container); - double scene_scale = (double)dst_box.width / (double)src_w; - cairo_translate(cairo, dst_box.x, dst_box.y); - cairo_scale(cairo, scene_scale, scene_scale); - cairo_set_source_surface(cairo, surface, 0, 0); - cairo_pattern_set_filter(cairo_get_source(cairo), CAIRO_FILTER_GOOD); - cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); - cairo_paint(cairo); - - cairo_destroy(cairo); - - return buffer; -} - struct lab_data_buffer * lab_img_render(struct lab_img *img, int width, int height, double scale) { @@ -158,13 +122,11 @@ lab_img_render(struct lab_img *img, int width, int height, double scale) case LAB_IMG_PNG: case LAB_IMG_XBM: case LAB_IMG_XPM: - buffer = render_cairo_surface(img->data->buffer->surface, - width, height, scale); + buffer = buffer_resize(img->data->buffer, width, height, scale); break; #if HAVE_RSVG case LAB_IMG_SVG: - buffer = img_svg_render(img->data->svg, width, height, - scale); + buffer = img_svg_render(img->data->svg, width, height, scale); break; #endif default: -- 2.52.0