From 8cc932391d041c51ebb7b0efaf4c2b2270d467ad Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 30 Apr 2014 19:55:56 -0700 Subject: [PATCH] GUAC-656: Implement transfer and copy. --- src/common/guac_surface.c | 130 +++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 2 deletions(-) diff --git a/src/common/guac_surface.c b/src/common/guac_surface.c index e4d76b72..9834451e 100644 --- a/src/common/guac_surface.c +++ b/src/common/guac_surface.c @@ -115,6 +115,126 @@ static void __guac_common_mark_dirty(guac_common_surface* surface, int x, int y, } +static void __guac_common_surface_transfer_int(guac_transfer_function op, uint32_t* src, uint32_t* dst) { + + switch (op) { + + case GUAC_TRANSFER_BINARY_BLACK: + *dst = 0xFF000000; + break; + + case GUAC_TRANSFER_BINARY_WHITE: + *dst = 0xFFFFFFFF; + break; + + case GUAC_TRANSFER_BINARY_SRC: + *dst = *src; + break; + + case GUAC_TRANSFER_BINARY_DEST: + /* NOP */ + break; + + case GUAC_TRANSFER_BINARY_NSRC: + *dst = ~(*src); + break; + + case GUAC_TRANSFER_BINARY_NDEST: + *dst = ~(*dst); + break; + + case GUAC_TRANSFER_BINARY_AND: + *dst = (*dst) & (*src); + break; + + case GUAC_TRANSFER_BINARY_NAND: + *dst = ~((*dst) & (*src)); + break; + + case GUAC_TRANSFER_BINARY_OR: + *dst = (*dst) | (*src); + break; + + case GUAC_TRANSFER_BINARY_NOR: + *dst = ~((*dst) | (*src)); + break; + + case GUAC_TRANSFER_BINARY_XOR: + *dst = (*dst) ^ (*src); + break; + + case GUAC_TRANSFER_BINARY_XNOR: + *dst = ~((*dst) ^ (*src)); + break; + + case GUAC_TRANSFER_BINARY_NSRC_AND: + *dst = (*dst) & ~(*src); + break; + + case GUAC_TRANSFER_BINARY_NSRC_NAND: + *dst = ~((*dst) & ~(*src)); + break; + + case GUAC_TRANSFER_BINARY_NSRC_OR: + *dst = (*dst) | ~(*src); + break; + + case GUAC_TRANSFER_BINARY_NSRC_NOR: + *dst = ~((*dst) | ~(*src)); + break; + + } +} + +static void __guac_common_surface_transfer(guac_common_surface* src, int sx, int sy, int w, int h, + guac_transfer_function op, guac_common_surface* dst, int dx, int dy) { + + unsigned char* src_buffer = src->buffer; + unsigned char* dst_buffer = dst->buffer; + + int x, y; + int src_stride, dst_stride; + int step = 1; + + /* Copy forwards only if destination is in a different surface or is before source */ + if (src != dst || dy < sy || (dy == sy && dx < sx)) { + src_buffer += src->stride*sy + 4*sx; + dst_buffer += dst->stride*dy + 4*dx; + src_stride = src->stride; + dst_stride = dst->stride; + step = 1; + } + + /* Otherwise, copy backwards */ + else { + src_buffer += src->stride*(sy+h-1) + 4*(sx+w-1); + dst_buffer += dst->stride*(dy+h-1) + 4*(dx+w-1); + src_stride = -src->stride; + dst_stride = -dst->stride; + step = -1; + } + + /* For each row */ + for (y=0; ylayer; const guac_layer* dst_layer = dst->layer; - /* TODO: Update backing surface */ + /* Update backing surface */ + cairo_surface_flush(src->surface); + cairo_surface_flush(dst->surface); + __guac_common_surface_transfer(src, sx, sy, w, h, GUAC_TRANSFER_BINARY_SRC, dst, dx, dy); /* Defer if combining */ if (__guac_common_should_combine(dst, dx, dy, w, h)) @@ -198,7 +321,10 @@ void guac_common_surface_transfer(guac_common_surface* src, int sx, int sy, int const guac_layer* src_layer = src->layer; const guac_layer* dst_layer = dst->layer; - /* TODO: Update backing surface */ + /* Update backing surface */ + cairo_surface_flush(src->surface); + cairo_surface_flush(dst->surface); + __guac_common_surface_transfer(src, sx, sy, w, h, op, dst, dx, dy); /* Defer if combining */ if (__guac_common_should_combine(dst, dx, dy, w, h))