From c5ada6631cc5106994a3b7921e2c047fbe652a99 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 5 May 2014 00:28:07 -0700 Subject: [PATCH] GUAC-667: Draw glyphs directly to surface. --- src/protocols/rdp/client.c | 7 -- src/protocols/rdp/client.h | 22 +----- src/protocols/rdp/guac_handlers.c | 2 - src/protocols/rdp/rdp_glyph.c | 109 ++++-------------------------- 4 files changed, 18 insertions(+), 122 deletions(-) diff --git a/src/protocols/rdp/client.c b/src/protocols/rdp/client.c index cfadc2b2..35294e78 100644 --- a/src/protocols/rdp/client.c +++ b/src/protocols/rdp/client.c @@ -705,13 +705,6 @@ int guac_client_init(guac_client* client, int argc, char** argv) { /* Send connection name */ guac_protocol_send_name(client->socket, settings->hostname); - /* Create glyph surfaces */ - guac_client_data->opaque_glyph_surface = cairo_image_surface_create( - CAIRO_FORMAT_RGB24, settings->width, settings->height); - - guac_client_data->trans_glyph_surface = cairo_image_surface_create( - CAIRO_FORMAT_ARGB32, settings->width, settings->height); - /* Create default surface */ guac_client_data->default_surface = guac_common_surface_alloc(client->socket, GUAC_DEFAULT_LAYER, settings->width, settings->height); diff --git a/src/protocols/rdp/client.h b/src/protocols/rdp/client.h index 6b1ebffe..726462cd 100644 --- a/src/protocols/rdp/client.h +++ b/src/protocols/rdp/client.h @@ -34,6 +34,7 @@ #include "rdp_settings.h" #include +#include #include #include @@ -99,26 +100,9 @@ typedef struct rdp_guac_client_data { int mouse_button_mask; /** - * Cairo surface which will receive all TRANSPARENT glyphs. + * Foreground color for any future glyphs. */ - cairo_surface_t* trans_glyph_surface; - - /** - * Cairo surface which will receive all OPAQUE glyphs. - */ - cairo_surface_t* opaque_glyph_surface; - - /** - * The current Cairo surface which will receive all drawn glyphs, - * depending on whether we are currently drawing transparent or - * opaque glyphs. - */ - cairo_surface_t* glyph_surface; - - /** - * Cairo instance for drawing to the current glyph surface. - */ - cairo_t* glyph_cairo; + uint32_t glyph_color; /** * The display. diff --git a/src/protocols/rdp/guac_handlers.c b/src/protocols/rdp/guac_handlers.c index b58eb3bf..f9c61ddf 100644 --- a/src/protocols/rdp/guac_handlers.c +++ b/src/protocols/rdp/guac_handlers.c @@ -94,8 +94,6 @@ int rdp_guac_client_free_handler(guac_client* client) { /* Free client data */ guac_common_clipboard_free(guac_client_data->clipboard); guac_common_surface_free(guac_client_data->default_surface); - cairo_surface_destroy(guac_client_data->opaque_glyph_surface); - cairo_surface_destroy(guac_client_data->trans_glyph_surface); free(guac_client_data); return 0; diff --git a/src/protocols/rdp/rdp_glyph.c b/src/protocols/rdp/rdp_glyph.c index f104cf70..09b480dc 100644 --- a/src/protocols/rdp/rdp_glyph.c +++ b/src/protocols/rdp/rdp_glyph.c @@ -100,15 +100,14 @@ void guac_rdp_glyph_draw(rdpContext* context, rdpGlyph* glyph, int x, int y) { guac_client* client = ((rdp_freerdp_context*) context)->client; rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data; + guac_common_surface* current_surface = guac_client_data->current_surface; + uint32_t fgcolor = guac_client_data->glyph_color; - /* Do not attempt to draw glyphs if glyph drawing is not begun */ - if (guac_client_data->glyph_cairo == NULL) - return; - - /* Use glyph as mask */ - cairo_mask_surface( - guac_client_data->glyph_cairo, - ((guac_rdp_glyph*) glyph)->surface, x, y); + /* Paint with glyph as mask */ + guac_common_surface_paint(current_surface, x, y, ((guac_rdp_glyph*) glyph)->surface, + (fgcolor & 0xFF0000) >> 16, + (fgcolor & 0x00FF00) >> 8, + fgcolor & 0x0000FF); } @@ -130,107 +129,29 @@ void guac_rdp_glyph_begindraw(rdpContext* context, rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data; - /* Convert foreground color */ - fgcolor = freerdp_color_convert_var(fgcolor, - guac_client_data->settings.color_depth, 32, - ((rdp_freerdp_context*) context)->clrconv); - /* Fill background with color if specified */ if (width != 0 && height != 0) { - /* Prepare for opaque glyphs */ - guac_client_data->glyph_surface = - guac_client_data->opaque_glyph_surface; - - /* Create cairo instance */ - guac_client_data->glyph_cairo = cairo_create( - guac_client_data->glyph_surface); - /* Convert background color */ bgcolor = freerdp_color_convert_var(bgcolor, guac_client_data->settings.color_depth, 32, ((rdp_freerdp_context*) context)->clrconv); - /* Fill background */ - cairo_rectangle(guac_client_data->glyph_cairo, - x, y, width, height); - - cairo_set_source_rgb(guac_client_data->glyph_cairo, - ((bgcolor & 0xFF0000) >> 16) / 255.0, - ((bgcolor & 0x00FF00) >> 8 ) / 255.0, - ( bgcolor & 0x0000FF ) / 255.0); - - cairo_fill(guac_client_data->glyph_cairo); + guac_common_surface_rect(guac_client_data->current_surface, x, y, width, height, + (bgcolor & 0xFF0000) >> 16, + (bgcolor & 0x00FF00) >> 8, + bgcolor & 0x0000FF); } - /* Otherwise, prepare for transparent glyphs */ - else { - - /* Select transparent glyph surface */ - guac_client_data->glyph_surface = - guac_client_data->trans_glyph_surface; - - guac_client_data->glyph_cairo = cairo_create( - guac_client_data->glyph_surface); - - /* Clear surface */ - cairo_set_operator(guac_client_data->glyph_cairo, - CAIRO_OPERATOR_SOURCE); - - cairo_set_source_rgba(guac_client_data->glyph_cairo, 0, 0, 0, 0); - cairo_paint(guac_client_data->glyph_cairo); - - /* Restore operator */ - cairo_set_operator(guac_client_data->glyph_cairo, - CAIRO_OPERATOR_OVER); - - } - - /* Prepare for glyph drawing */ - cairo_set_source_rgb(guac_client_data->glyph_cairo, - ((fgcolor & 0xFF0000) >> 16) / 255.0, - ((fgcolor & 0x00FF00) >> 8 ) / 255.0, - ( fgcolor & 0x0000FF ) / 255.0); + /* Convert foreground color */ + guac_client_data->glyph_color = freerdp_color_convert_var(fgcolor, + guac_client_data->settings.color_depth, 32, ((rdp_freerdp_context*) context)->clrconv); } void guac_rdp_glyph_enddraw(rdpContext* context, int x, int y, int width, int height, UINT32 fgcolor, UINT32 bgcolor) { - - guac_client* client = ((rdp_freerdp_context*) context)->client; - rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data; - guac_common_surface* current_surface = ((rdp_guac_client_data*) client->data)->current_surface; - - /* Use glyph surface to provide image data for glyph rectangle */ - cairo_surface_t* glyph_surface = guac_client_data->glyph_surface; - int stride = cairo_image_surface_get_stride(glyph_surface); - - /* Calculate bounds */ - int max_width = cairo_image_surface_get_width(glyph_surface) - x; - int max_height = cairo_image_surface_get_height(glyph_surface) - y; - - /* Ensure dimensions of glyph do not exceed bounds */ - if (width > max_width) width = max_width; - if (height > max_height) height = max_height; - - /* Ensure data is ready */ - cairo_surface_flush(glyph_surface); - - /* Create surface for subsection with text */ - 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_format(glyph_surface), - width, height, stride); - - /* Send surface with all glyphs to current surface */ - guac_common_surface_draw(current_surface, x, y, surface); - - /* Destroy surface */ - cairo_surface_destroy(surface); - - /* Destroy cairo instance */ - cairo_destroy(guac_client_data->glyph_cairo); - + /* IGNORE */ }