aboutsummaryrefslogtreecommitdiff
path: root/util/region.c
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2018-02-09 09:38:48 -0500
committerGitHub <noreply@github.com>2018-02-09 09:38:48 -0500
commit34489dca16ef9e7fd05c161b8b4f2fd5ce5e4ef0 (patch)
tree2a90beb98aacd85bbc5bd30df998b4e7c92ec3e7 /util/region.c
parent09c2626e32fd0eadc4b95a4f36b34f6bde79f6f4 (diff)
parentcdd55b5d19470981ad71f8e6d31bd8152e44364b (diff)
Merge pull request #571 from emersion/output-damage
Output damage tracking
Diffstat (limited to 'util/region.c')
-rw-r--r--util/region.c130
1 files changed, 130 insertions, 0 deletions
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);
+}