aboutsummaryrefslogtreecommitdiff
path: root/src/region.h
diff options
context:
space:
mode:
authorallusive-dev <[email protected]>2023-09-19 17:47:33 +1000
committerallusive-dev <[email protected]>2023-09-19 17:47:33 +1000
commita93aba600b1c5d019b680b9f4ff3fa85d5d43a60 (patch)
tree77f8152222655657472a70e0bfa413a0495dd555 /src/region.h
parentreset (diff)
downloadcompfy-a93aba600b1c5d019b680b9f4ff3fa85d5d43a60.tar.xz
compfy-a93aba600b1c5d019b680b9f4ff3fa85d5d43a60.zip
Fixed broken files/code and other errors
Diffstat (limited to 'src/region.h')
-rw-r--r--src/region.h100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/region.h b/src/region.h
new file mode 100644
index 0000000..bda66e2
--- /dev/null
+++ b/src/region.h
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) 2018 Yuxuan Shui <[email protected]>
+#pragma once
+#include <pixman.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <xcb/xcb.h>
+
+#include "log.h"
+#include "utils.h"
+
+typedef struct pixman_region32 pixman_region32_t;
+typedef struct pixman_box32 pixman_box32_t;
+typedef pixman_region32_t region_t;
+typedef pixman_box32_t rect_t;
+
+RC_TYPE(region_t, rc_region, pixman_region32_init, pixman_region32_fini, static inline)
+
+static inline void dump_region(const region_t *x) {
+ if (log_get_level_tls() < LOG_LEVEL_TRACE) {
+ return;
+ }
+ int nrects;
+ const rect_t *rects = pixman_region32_rectangles((region_t *)x, &nrects);
+ log_trace("nrects: %d", nrects);
+ for (int i = 0; i < nrects; i++)
+ log_trace("(%d, %d) - (%d, %d)", rects[i].x1, rects[i].y1, rects[i].x2,
+ rects[i].y2);
+}
+
+/// Convert one xcb rectangle to our rectangle type
+static inline rect_t from_x_rect(const xcb_rectangle_t *rect) {
+ return (rect_t){
+ .x1 = rect->x,
+ .y1 = rect->y,
+ .x2 = rect->x + rect->width,
+ .y2 = rect->y + rect->height,
+ };
+}
+
+/// Convert an array of xcb rectangles to our rectangle type
+/// Returning an array that needs to be freed
+static inline rect_t *from_x_rects(int nrects, const xcb_rectangle_t *rects) {
+ rect_t *ret = ccalloc(nrects, rect_t);
+ for (int i = 0; i < nrects; i++) {
+ ret[i] = from_x_rect(rects + i);
+ }
+ return ret;
+}
+
+/**
+ * Resize a region.
+ */
+static inline void _resize_region(const region_t *region, region_t *output, int dx,
+ int dy) {
+ if (!region || !output) {
+ return;
+ }
+ if (!dx && !dy) {
+ if (region != output) {
+ pixman_region32_copy(output, (region_t *)region);
+ }
+ return;
+ }
+ // Loop through all rectangles
+ int nrects;
+ int nnewrects = 0;
+ const rect_t *rects = pixman_region32_rectangles((region_t *)region, &nrects);
+ auto newrects = ccalloc(nrects, rect_t);
+ for (int i = 0; i < nrects; i++) {
+ int x1 = rects[i].x1 - dx;
+ int y1 = rects[i].y1 - dy;
+ int x2 = rects[i].x2 + dx;
+ int y2 = rects[i].y2 + dy;
+ int wid = x2 - x1;
+ int hei = y2 - y1;
+ if (wid <= 0 || hei <= 0) {
+ continue;
+ }
+ newrects[nnewrects] =
+ (rect_t){.x1 = x1, .x2 = x2, .y1 = y1, .y2 = y2};
+ ++nnewrects;
+ }
+
+ pixman_region32_fini(output);
+ pixman_region32_init_rects(output, newrects, nnewrects);
+
+ free(newrects);
+}
+
+static inline region_t resize_region(const region_t *region, int dx, int dy) {
+ region_t ret;
+ pixman_region32_init(&ret);
+ _resize_region(region, &ret, dx, dy);
+ return ret;
+}
+
+static inline void resize_region_in_place(region_t *region, int dx, int dy) {
+ return _resize_region(region, region, dx, dy);
+}