mirror of
https://github.com/labwc/labwc.git
synced 2026-03-11 05:33:49 -04:00
buffer: add buffer_resize()
This commit is contained in:
parent
0657a1d767
commit
82b0235aca
3 changed files with 44 additions and 40 deletions
|
|
@ -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,
|
struct lab_data_buffer *buffer_create_from_data(void *pixel_data, uint32_t width,
|
||||||
uint32_t height, uint32_t stride);
|
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 */
|
#endif /* LABWC_BUFFER_H */
|
||||||
|
|
|
||||||
35
src/buffer.c
35
src/buffer.c
|
|
@ -29,6 +29,7 @@
|
||||||
#include <drm_fourcc.h>
|
#include <drm_fourcc.h>
|
||||||
#include <wlr/interfaces/wlr_buffer.h>
|
#include <wlr/interfaces/wlr_buffer.h>
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
#include "common/box.h"
|
||||||
#include "common/mem.h"
|
#include "common/mem.h"
|
||||||
|
|
||||||
static const struct wlr_buffer_impl data_buffer_impl;
|
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;
|
buffer->surface_owns_data = false;
|
||||||
return buffer;
|
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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,42 +112,6 @@ lab_img_add_modifier(struct lab_img *img, lab_img_modifier_func_t modifier)
|
||||||
*mod = 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 *
|
struct lab_data_buffer *
|
||||||
lab_img_render(struct lab_img *img, int width, int height, double scale)
|
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_PNG:
|
||||||
case LAB_IMG_XBM:
|
case LAB_IMG_XBM:
|
||||||
case LAB_IMG_XPM:
|
case LAB_IMG_XPM:
|
||||||
buffer = render_cairo_surface(img->data->buffer->surface,
|
buffer = buffer_resize(img->data->buffer, width, height, scale);
|
||||||
width, height, scale);
|
|
||||||
break;
|
break;
|
||||||
#if HAVE_RSVG
|
#if HAVE_RSVG
|
||||||
case LAB_IMG_SVG:
|
case LAB_IMG_SVG:
|
||||||
buffer = img_svg_render(img->data->svg, width, height,
|
buffer = img_svg_render(img->data->svg, width, height, scale);
|
||||||
scale);
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue