handle the other transformations for screenshots

This handles all current transformations for outputs properly.
This ensures an output is drawn in readable orientation/flipping no
matter the actual transformations applied to it.
This commit is contained in:
Markus Ongyerth 2018-01-31 16:05:33 +01:00
parent 4afc933ea4
commit 3a404e4f8d
1 changed files with 66 additions and 16 deletions

View File

@ -48,7 +48,7 @@ struct screenshooter_output {
struct wl_output *output; struct wl_output *output;
struct wl_buffer *buffer; struct wl_buffer *buffer;
int width, height, offset_x, offset_y; int width, height, offset_x, offset_y;
int transform; enum wl_output_transform transform;
void *data; void *data;
struct wl_list link; struct wl_list link;
}; };
@ -161,26 +161,76 @@ static void write_image(const char *filename, int width, int height) {
struct screenshooter_output *output, *next; struct screenshooter_output *output, *next;
wl_list_for_each_safe(output, next, &output_list, link) { wl_list_for_each_safe(output, next, &output_list, link) {
int output_stride = output->width * 4; int output_stride = output->width * 4;
void *s = output->data; uint32_t *src = (uint32_t *)output->data;
void *d = data + (output->offset_y - min_y) * buffer_stride + uint32_t *dst = (uint32_t *)(data +
(output->offset_x - min_x) * 4; (output->offset_y - min_y) * buffer_stride +
(output->offset_x - min_x) * 4);
if (output->transform == WL_OUTPUT_TRANSFORM_90) { switch (output->transform) {
uint32_t *ss = s; case WL_OUTPUT_TRANSFORM_NORMAL:
uint32_t *sd = d; for (int i = 0; i < output->height; i++) {
memcpy(dst, src, output_stride);
dst += width;
src += output->width;
}
break;
case WL_OUTPUT_TRANSFORM_FLIPPED:
for (int i = 0; i < output->height; ++i) {
for (int j = 0; j < output->width; ++j) {
dst[i * width + j] =
src[i * output->width + output->width - j];
}
}
break;
case WL_OUTPUT_TRANSFORM_90:
for (int i = 0; i < output->width; ++i) { for (int i = 0; i < output->width; ++i) {
for (int j = 0; j < output->height; ++j) { for (int j = 0; j < output->height; ++j) {
sd[i * width + j] dst[i * width + j] =
= ss[j * output->width + (output->width - i)]; src[j * output->width + output->width - i];
} }
} }
} else { break;
for (int i = 0; i < output->height; i++) { case WL_OUTPUT_TRANSFORM_FLIPPED_90:
memcpy(d, s, output_stride); for (int i = 0; i < output->width; ++i) {
d += buffer_stride; for (int j = 0; j < output->height; ++j) {
s += output_stride; dst[i * width + j] =
src[(output->height - j) * output->width + output->width - i];
} }
} }
break;
case WL_OUTPUT_TRANSFORM_180:
for (int i = 0; i < output->height; ++i) {
for (int j = 0; j < output->width; ++j) {
dst[i * width + j] =
src[(output->height - i) * output->width + output->width - j];
}
}
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
for (int i = 0; i < output->height; ++i) {
for (int j = 0; j < output->width; ++j) {
dst[i * width + j] =
src[(output->height - i) * output->width + j];
}
}
break;
case WL_OUTPUT_TRANSFORM_270:
for (int i = 0; i < output->width; ++i) {
for (int j = 0; j < output->height; ++j) {
dst[i * width + j] =
src[(output->height - j) * output->width + i];
}
}
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
for (int i = 0; i < output->width; ++i) {
for (int j = 0; j < output->height; ++j) {
dst[i * width + j] =
src[j * output->width + i];
}
}
break;
}
free(output); free(output);
} }