Fix guac_rdp_clip_rect() handling of completely clipped rects.

This commit is contained in:
Michael Jumper 2013-07-19 12:21:34 -07:00
parent 77999e6371
commit 4a3a530fde
4 changed files with 37 additions and 25 deletions

View File

@ -619,7 +619,7 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
} }
void guac_rdp_clip_rect(rdp_guac_client_data* data, int* x, int* y, int* w, int* h) { int guac_rdp_clip_rect(rdp_guac_client_data* data, int* x, int* y, int* w, int* h) {
if (data->bounded) { if (data->bounded) {
@ -631,18 +631,18 @@ void guac_rdp_clip_rect(rdp_guac_client_data* data, int* x, int* y, int* w, int*
/* Clip left */ /* Clip left */
if (clipped_left < data->bounds_left) clipped_left = data->bounds_left; if (clipped_left < data->bounds_left) clipped_left = data->bounds_left;
else if (clipped_left > data->bounds_right) clipped_left = data->bounds_right; else if (clipped_left > data->bounds_right) return 1;
/* Clip right */ /* Clip right */
if (clipped_right < data->bounds_left) clipped_right = data->bounds_left; if (clipped_right < data->bounds_left) return 1;
else if (clipped_right > data->bounds_right) clipped_right = data->bounds_right; else if (clipped_right > data->bounds_right) clipped_right = data->bounds_right;
/* Clip top */ /* Clip top */
if (clipped_top < data->bounds_top) clipped_top = data->bounds_top; if (clipped_top < data->bounds_top) clipped_top = data->bounds_top;
else if (clipped_top > data->bounds_bottom) clipped_top = data->bounds_bottom; else if (clipped_top > data->bounds_bottom) return 1;
/* Clip bottom */ /* Clip bottom */
if (clipped_bottom < data->bounds_top) clipped_bottom = data->bounds_top; if (clipped_bottom < data->bounds_top) return 1;
else if (clipped_bottom > data->bounds_bottom) clipped_bottom = data->bounds_bottom; else if (clipped_bottom > data->bounds_bottom) clipped_bottom = data->bounds_bottom;
/* Store new rect dimensions */ /* Store new rect dimensions */
@ -653,6 +653,8 @@ void guac_rdp_clip_rect(rdp_guac_client_data* data, int* x, int* y, int* w, int*
} }
return 0;
} }

View File

@ -222,8 +222,11 @@ typedef struct rdp_freerdp_context {
/** /**
* Given the coordinates and dimensions of a rectangle, clips the rectangle to be * Given the coordinates and dimensions of a rectangle, clips the rectangle to be
* within the clipping bounds of the client data, if clipping is active. * within the clipping bounds of the client data, if clipping is active.
*
* Returns 0 if the rectangle given is visible at all, and 1 if the entire
* rectangls is outside the clipping rectangle and this invisible.
*/ */
void guac_rdp_clip_rect(rdp_guac_client_data* data, int* x, int* y, int* w, int* h); int guac_rdp_clip_rect(rdp_guac_client_data* data, int* x, int* y, int* w, int* h);
#endif #endif

View File

@ -115,7 +115,8 @@ void guac_rdp_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) {
/* Clip operation to bounds */ /* Clip operation to bounds */
rdp_guac_client_data* data = (rdp_guac_client_data*) client->data; rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
guac_rdp_clip_rect(data, &x, &y, &w, &h); if (guac_rdp_clip_rect(data, &x, &y, &w, &h))
return;
switch (dstblt->bRop) { switch (dstblt->bRop) {
@ -201,7 +202,8 @@ void guac_rdp_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) {
"negotiated client capabilities)"); "negotiated client capabilities)");
/* Clip operation to bounds */ /* Clip operation to bounds */
guac_rdp_clip_rect(data, &x, &y, &w, &h); if (guac_rdp_clip_rect(data, &x, &y, &w, &h))
return;
/* Render rectangle based on ROP */ /* Render rectangle based on ROP */
switch (patblt->bRop) { switch (patblt->bRop) {
@ -289,7 +291,8 @@ void guac_rdp_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) {
/* Clip operation to bounds */ /* Clip operation to bounds */
rdp_guac_client_data* data = (rdp_guac_client_data*) client->data; rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
guac_rdp_clip_rect(data, &x, &y, &w, &h); if (guac_rdp_clip_rect(data, &x, &y, &w, &h))
return;
/* Update source coordinates */ /* Update source coordinates */
x_src += x - scrblt->nLeftRect; x_src += x - scrblt->nLeftRect;
@ -326,7 +329,8 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
} }
/* Clip operation to bounds */ /* Clip operation to bounds */
guac_rdp_clip_rect(data, &x, &y, &w, &h); if (guac_rdp_clip_rect(data, &x, &y, &w, &h))
return;
/* Update source coordinates */ /* Update source coordinates */
x_src += x - memblt->nLeftRect; x_src += x - memblt->nLeftRect;
@ -431,7 +435,8 @@ void guac_rdp_gdi_opaquerect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect
int h = opaque_rect->nHeight; int h = opaque_rect->nHeight;
/* Clip operation to bounds */ /* Clip operation to bounds */
guac_rdp_clip_rect(data, &x, &y, &w, &h); if (guac_rdp_clip_rect(data, &x, &y, &w, &h))
return;
guac_protocol_send_rect(client->socket, current_layer, x, y, w, h); guac_protocol_send_rect(client->socket, current_layer, x, y, w, h);

View File

@ -222,24 +222,26 @@ void guac_rdp_glyph_enddraw(rdpContext* context,
if (height > max_height) height = max_height; if (height > max_height) height = max_height;
/* Clip operation to clipping region, if any */ /* Clip operation to clipping region, if any */
guac_rdp_clip_rect(guac_client_data, &x, &y, &width, &height); if (!guac_rdp_clip_rect(guac_client_data, &x, &y, &width, &height)) {
/* Ensure data is ready */ /* Ensure data is ready */
cairo_surface_flush(glyph_surface); cairo_surface_flush(glyph_surface);
/* Create surface for subsection with text */ /* Create surface for subsection with text */
cairo_surface_t* surface = cairo_image_surface_create_for_data( cairo_surface_t* surface = cairo_image_surface_create_for_data(
cairo_image_surface_get_data(glyph_surface) + 4*x + y*stride, cairo_image_surface_get_data(glyph_surface) + 4*x + y*stride,
cairo_image_surface_get_format(glyph_surface), cairo_image_surface_get_format(glyph_surface),
width, height, stride); width, height, stride);
/* Send surface with all glyphs to layer */ /* Send surface with all glyphs to layer */
guac_protocol_send_png(client->socket, guac_protocol_send_png(client->socket,
GUAC_COMP_OVER, current_layer, x, y, GUAC_COMP_OVER, current_layer, x, y,
surface); surface);
/* Destroy surface */ /* Destroy surface */
cairo_surface_destroy(surface); cairo_surface_destroy(surface);
}
/* Destroy cairo instance */ /* Destroy cairo instance */
cairo_destroy(guac_client_data->glyph_cairo); cairo_destroy(guac_client_data->glyph_cairo);