aboutsummaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/meson.build2
-rw-r--r--util/region.c130
2 files changed, 132 insertions, 0 deletions
diff --git a/util/meson.build b/util/meson.build
index 21930693..34aa428b 100644
--- a/util/meson.build
+++ b/util/meson.build
@@ -3,6 +3,8 @@ lib_wlr_util = static_library(
files(
'log.c',
'os-compatibility.c',
+ 'region.c',
),
include_directories: wlr_inc,
+ dependencies: [wayland_server, pixman],
)
diff --git a/util/region.c b/util/region.c
new file mode 100644
index 00000000..1bde0cb8
--- /dev/null
+++ b/util/region.c
@@ -0,0 +1,130 @@
+#include <stdlib.h>
+#include <math.h>
+#include <wlr/util/region.h>
+
+void wlr_region_scale(pixman_region32_t *dst, pixman_region32_t *src,
+ float scale) {
+ if (scale == 1) {
+ pixman_region32_copy(dst, src);
+ return;
+ }
+
+ int nrects;
+ pixman_box32_t *src_rects = pixman_region32_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 = floor(src_rects[i].x1 * scale);
+ dst_rects[i].x2 = ceil(src_rects[i].x2 * scale);
+ dst_rects[i].y1 = floor(src_rects[i].y1 * scale);
+ dst_rects[i].y2 = ceil(src_rects[i].y2 * scale);
+ }
+
+ pixman_region32_fini(dst);
+ pixman_region32_init_rects(dst, dst_rects, nrects);
+ free(dst_rects);
+}
+
+void wlr_region_transform(pixman_region32_t *dst, pixman_region32_t *src,
+ enum wl_output_transform transform, int width, int height) {
+ if (transform == WL_OUTPUT_TRANSFORM_NORMAL) {
+ pixman_region32_copy(dst, src);
+ return;
+ }
+
+ int nrects;
+ pixman_box32_t *src_rects = pixman_region32_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) {
+ switch (transform) {
+ case WL_OUTPUT_TRANSFORM_NORMAL:
+ dst_rects[i].x1 = src_rects[i].x1;
+ dst_rects[i].y1 = src_rects[i].y1;
+ dst_rects[i].x2 = src_rects[i].x2;
+ dst_rects[i].y2 = src_rects[i].y2;
+ break;
+ case WL_OUTPUT_TRANSFORM_90:
+ dst_rects[i].x1 = src_rects[i].y1;
+ dst_rects[i].y1 = width - src_rects[i].x2;
+ dst_rects[i].x2 = src_rects[i].y2;
+ dst_rects[i].y2 = width - src_rects[i].x1;
+ break;
+ case WL_OUTPUT_TRANSFORM_180:
+ dst_rects[i].x1 = width - src_rects[i].x2;
+ dst_rects[i].y1 = height - src_rects[i].y2;
+ dst_rects[i].x2 = width - src_rects[i].x1;
+ dst_rects[i].y2 = height - src_rects[i].y1;
+ break;
+ case WL_OUTPUT_TRANSFORM_270:
+ dst_rects[i].x1 = height - src_rects[i].y2;
+ dst_rects[i].y1 = src_rects[i].x1;
+ dst_rects[i].x2 = height - src_rects[i].y1;
+ dst_rects[i].y2 = src_rects[i].x2;
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED:
+ dst_rects[i].x1 = width - src_rects[i].x2;
+ dst_rects[i].y1 = src_rects[i].y1;
+ dst_rects[i].x2 = width - src_rects[i].x1;
+ dst_rects[i].y2 = src_rects[i].y2;
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+ dst_rects[i].x1 = height - src_rects[i].y2;
+ dst_rects[i].y1 = width - src_rects[i].x2;
+ dst_rects[i].x2 = height - src_rects[i].y1;
+ dst_rects[i].y2 = width - src_rects[i].x1;
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+ dst_rects[i].x1 = src_rects[i].x1;
+ dst_rects[i].y1 = height - src_rects[i].y2;
+ dst_rects[i].x2 = src_rects[i].x2;
+ dst_rects[i].y2 = height - src_rects[i].y1;
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+ dst_rects[i].x1 = src_rects[i].y1;
+ dst_rects[i].y1 = src_rects[i].x1;
+ dst_rects[i].x2 = src_rects[i].y2;
+ dst_rects[i].y2 = src_rects[i].x2;
+ break;
+ }
+ }
+
+ pixman_region32_fini(dst);
+ pixman_region32_init_rects(dst, dst_rects, nrects);
+ free(dst_rects);
+}
+
+void wlr_region_expand(pixman_region32_t *dst, pixman_region32_t *src,
+ int distance) {
+ if (distance == 0) {
+ pixman_region32_copy(dst, src);
+ return;
+ }
+
+ int nrects;
+ pixman_box32_t *src_rects = pixman_region32_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 = src_rects[i].x1 - distance;
+ dst_rects[i].x2 = src_rects[i].x2 + distance;
+ dst_rects[i].y1 = src_rects[i].y1 - distance;
+ dst_rects[i].y2 = src_rects[i].y2 + distance;
+ }
+
+ pixman_region32_fini(dst);
+ pixman_region32_init_rects(dst, dst_rects, nrects);
+ free(dst_rects);
+}