GUAC-667: Add masked paint operation.
This commit is contained in:
parent
1047c6192c
commit
3554e88efa
@ -29,6 +29,8 @@
|
||||
#include <guacamole/socket.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/**
|
||||
* The width of an update which should be considered negible and thus
|
||||
@ -365,6 +367,45 @@ static void __guac_common_surface_put(unsigned char* src_buffer, int src_stride,
|
||||
|
||||
}
|
||||
|
||||
static void __guac_common_surface_fill_mask(unsigned char* src_buffer, int src_stride,
|
||||
int sx, int sy, int w, int h,
|
||||
guac_common_surface* dst, int dx, int dy,
|
||||
int red, int green, int blue) {
|
||||
|
||||
unsigned char* dst_buffer = dst->buffer;
|
||||
int dst_stride = dst->stride;
|
||||
|
||||
uint32_t color = 0xFF000000 | (red << 16) | (green << 8) | blue;
|
||||
int x, y;
|
||||
|
||||
src_buffer += src_stride*sy + 4*sx;
|
||||
dst_buffer += dst_stride*dy + 4*dx;
|
||||
|
||||
/* For each row */
|
||||
for (y=0; y<h; y++) {
|
||||
|
||||
uint32_t* src_current = (uint32_t*) src_buffer;
|
||||
uint32_t* dst_current = (uint32_t*) dst_buffer;
|
||||
|
||||
/* Stencil row */
|
||||
for (x=0; x<w; x++) {
|
||||
|
||||
/* Fill with color if opaque */
|
||||
if (*src_current & 0xFF000000)
|
||||
*dst_current = color;
|
||||
|
||||
src_current++;
|
||||
dst_current++;
|
||||
}
|
||||
|
||||
/* Next row */
|
||||
src_buffer += src_stride;
|
||||
dst_buffer += dst_stride;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
@ -551,6 +592,34 @@ void guac_common_surface_draw(guac_common_surface* surface, int x, int y, cairo_
|
||||
|
||||
}
|
||||
|
||||
void guac_common_surface_paint(guac_common_surface* surface, int x, int y, cairo_surface_t* src,
|
||||
int red, int green, int blue) {
|
||||
|
||||
unsigned char* buffer = cairo_image_surface_get_data(src);
|
||||
int stride = cairo_image_surface_get_stride(src);
|
||||
int w = cairo_image_surface_get_width(src);
|
||||
int h = cairo_image_surface_get_height(src);
|
||||
|
||||
int sx = 0;
|
||||
int sy = 0;
|
||||
|
||||
/* Clip operation */
|
||||
__guac_common_bound_rect(surface, &x, &y, &w, &h, &sx, &sy);
|
||||
if (w <= 0 || h <= 0)
|
||||
return;
|
||||
|
||||
/* Flush if not combining */
|
||||
if (!__guac_common_should_combine(surface, x, y, w, h, 0))
|
||||
guac_common_surface_flush(surface);
|
||||
|
||||
/* Always defer draws */
|
||||
__guac_common_mark_dirty(surface, x, y, w, h);
|
||||
|
||||
/* Update backing surface */
|
||||
__guac_common_surface_fill_mask(buffer, stride, sx, sy, w, h, surface, x, y, red, green, blue);
|
||||
|
||||
}
|
||||
|
||||
void guac_common_surface_copy(guac_common_surface* src, int sx, int sy, int w, int h,
|
||||
guac_common_surface* dst, int dx, int dy) {
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include <guacamole/protocol.h>
|
||||
#include <guacamole/socket.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Surface which backs a Guacamole buffer or layer, automatically
|
||||
* combining updates when possible.
|
||||
@ -160,6 +162,22 @@ void guac_common_surface_resize(guac_common_surface* surface, int w, int h);
|
||||
*/
|
||||
void guac_common_surface_draw(guac_common_surface* surface, int x, int y, cairo_surface_t* src);
|
||||
|
||||
/**
|
||||
* Paints to the given guac_common_surface using the given data as a stencil,
|
||||
* filling opaque regions with the specified color, and leaving transparent
|
||||
* regions untouched.
|
||||
*
|
||||
* @param surface The surface to draw to.
|
||||
* @param x The X coordinate of the draw location.
|
||||
* @param y The Y coordinate of the draw location.
|
||||
* @param src The Cairo surface to retrieve data from.
|
||||
* @param red The red component of the fill color.
|
||||
* @param green The green component of the fill color.
|
||||
* @param blue The blue component of the fill color.
|
||||
*/
|
||||
void guac_common_surface_paint(guac_common_surface* surface, int x, int y, cairo_surface_t* src,
|
||||
int red, int green, int blue);
|
||||
|
||||
/**
|
||||
* Copies a rectangle of data between two surfaces.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user