From 2ab8f41750caa8a270fbdf9dc94cc2e25af0eb11 Mon Sep 17 00:00:00 2001 From: Loukas Agorgianitis Date: Mon, 28 Apr 2025 17:49:36 +0300 Subject: [PATCH] util/region: add fractional region helpers Signed-off-by: Loukas Agorgianitis --- include/wlr/util/region.h | 25 ++++++++++++++++++++ util/region.c | 48 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/include/wlr/util/region.h b/include/wlr/util/region.h index ccd926fd1..592cb81ef 100644 --- a/include/wlr/util/region.h +++ b/include/wlr/util/region.h @@ -44,6 +44,31 @@ void wlr_region_scale(pixman_region32_t *dst, const pixman_region32_t *src, void wlr_region_scale_xy(pixman_region32_t *dst, const pixman_region32_t *src, float scale_x, float scale_y); +/** + * Scale a fractional region by the specified factor. + * + * The resulting coordinates are rounded to nearest integer. + * + * Also see wlr_region_scalef_xy(). + */ +void wlr_region_scalef(pixman_region32_t *dst, const pixman_region64f_t *src, + float scale); + +/** + * Scale a region by the specified factors. + * + * The X and Y coordinates are scaled separately by scale_x and scale_y. + * + * The resulting coordinates are rounded to nearest integer. + */ +void wlr_region_scalef_xy(pixman_region32_t *dst, const pixman_region64f_t *src, + float scale_x, float scale_y); + +/** + * Copy an integer region into a fractional region. + */ +void wlr_region64f_copy_from_region32(pixman_region64f_t *dst, const pixman_region32_t *src); + /** * Applies a transform to a region inside a box of size `width` x `height`. */ diff --git a/util/region.c b/util/region.c index b74c55e54..bf95c4fb5 100644 --- a/util/region.c +++ b/util/region.c @@ -36,6 +36,54 @@ void wlr_region_scale_xy(pixman_region32_t *dst, const pixman_region32_t *src, free(dst_rects); } +void wlr_region_scalef(pixman_region32_t *dst, const pixman_region64f_t *src, + float scale) { + wlr_region_scalef_xy(dst, src, scale, scale); +} + +void wlr_region_scalef_xy(pixman_region32_t *dst, const pixman_region64f_t *src, + float scale_x, float scale_y) { + int nrects; + const pixman_box64f_t *src_rects = pixman_region64f_rectangles(src, &nrects); + + pixman_box32_t *dst_rects = malloc(nrects * sizeof(pixman_box32_t)); + if (dst_rects == NULL) { + return; + } + + for (int i = 0; i < nrects; ++i) { + dst_rects[i].x1 = round(src_rects[i].x1 * scale_x); + dst_rects[i].x2 = round(src_rects[i].x2 * scale_x); + dst_rects[i].y1 = round(src_rects[i].y1 * scale_y); + dst_rects[i].y2 = round(src_rects[i].y2 * scale_y); + } + + pixman_region32_fini(dst); + pixman_region32_init_rects(dst, dst_rects, nrects); + free(dst_rects); +} + +void wlr_region64f_copy_from_region32(pixman_region64f_t *dst, const pixman_region32_t *src) { + int nrects; + const pixman_box32_t *src_rects = pixman_region32_rectangles(src, &nrects); + + pixman_box64f_t *dst_rects = malloc(nrects * sizeof(pixman_box64f_t)); + if (dst_rects == NULL) { + return; + } + + for (int i = 0; i < nrects; ++i) { + dst_rects[i].x1 = src_rects[i].x1; + dst_rects[i].x2 = src_rects[i].x2; + dst_rects[i].y1 = src_rects[i].y1; + dst_rects[i].y2 = src_rects[i].y2; + } + + pixman_region64f_fini(dst); + pixman_region64f_init_rects(dst, dst_rects, nrects); + free(dst_rects); +} + void wlr_region_transform(pixman_region32_t *dst, const pixman_region32_t *src, enum wl_output_transform transform, int width, int height) { if (transform == WL_OUTPUT_TRANSFORM_NORMAL) {