From 572810e2a91afc79c8c776acb83815557b3537d5 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 5 Apr 2012 22:38:10 -0700 Subject: [PATCH] Working glyph rendering (except for transparent text) --- include/client.h | 9 ------ src/client.c | 15 +++++++--- src/rdp_glyph.c | 80 +++++++++++++++++++++++++++++------------------------- 3 files changed, 54 insertions(+), 50 deletions(-) diff --git a/include/client.h b/include/client.h index ac86911..246834f 100644 --- a/include/client.h +++ b/include/client.h @@ -47,12 +47,6 @@ #define RDP_DEFAULT_PORT 3389 -typedef struct guac_rdp_color { - int red; - int green; - int blue; -} guac_rdp_color; - typedef struct rdp_guac_client_data { freerdp* rdp_inst; @@ -60,9 +54,6 @@ typedef struct rdp_guac_client_data { int mouse_button_mask; - guac_rdp_color foreground; - guac_rdp_color background; - /** * Cairo surface which will receive all drawn glyphs. */ diff --git a/src/client.c b/src/client.c index d7f0b8d..e71d839 100644 --- a/src/client.c +++ b/src/client.c @@ -193,10 +193,6 @@ boolean rdp_freerdp_post_connect(freerdp* instance) { client->mouse_handler = rdp_guac_client_mouse_handler; client->key_handler = rdp_guac_client_key_handler; - /* Send size */ - guac_protocol_send_size(client->socket, GUAC_DEFAULT_LAYER, - instance->settings->width, instance->settings->height); - return true; } @@ -393,6 +389,17 @@ int guac_client_init(guac_client* client, int argc, char** argv) { /* Send connection name */ guac_protocol_send_name(client->socket, settings->window_title); + /* Send size */ + guac_protocol_send_size(client->socket, GUAC_DEFAULT_LAYER, + settings->width, settings->height); + + /* Create glyph surface and cairo instance */ + guac_client_data->glyph_surface = cairo_image_surface_create( + CAIRO_FORMAT_RGB24, settings->width, settings->height); + + guac_client_data->glyph_cairo = cairo_create( + guac_client_data->glyph_surface); + /* Success */ return 0; diff --git a/src/rdp_glyph.c b/src/rdp_glyph.c index 8a65c6f..c259725 100644 --- a/src/rdp_glyph.c +++ b/src/rdp_glyph.c @@ -39,6 +39,7 @@ #include #include +#include #include "client.h" #include "rdp_glyph.h" @@ -100,16 +101,16 @@ 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; - + + /* 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); - /* Fill rectangle with foreground */ - cairo_rectangle(guac_client_data->glyph_cairo, x, y, glyph->cx, glyph->cy); - cairo_fill(guac_client_data->glyph_cairo); - } void guac_rdp_glyph_free(rdpContext* context, rdpGlyph* glyph) { @@ -127,47 +128,40 @@ void guac_rdp_glyph_begindraw(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; - - bgcolor = freerdp_color_convert_var(bgcolor, - context->instance->settings->color_depth, 32, - ((rdp_freerdp_context*) context)->clrconv); + rdp_guac_client_data* guac_client_data = + (rdp_guac_client_data*) client->data; + /* Convert foreground color */ fgcolor = freerdp_color_convert_var(fgcolor, context->instance->settings->color_depth, 32, ((rdp_freerdp_context*) context)->clrconv); - guac_client_data->foreground.blue = fgcolor & 0x0000FF; - guac_client_data->foreground.green = (fgcolor & 0x00FF00) >> 8; - guac_client_data->foreground.red = (fgcolor & 0xFF0000) >> 16; + /* Fill background with color if specified */ + if (width != 0 && height != 0) { - guac_client_data->background.blue = bgcolor & 0x0000FF; - guac_client_data->background.green = (bgcolor & 0x00FF00) >> 8; - guac_client_data->background.red = (bgcolor & 0xFF0000) >> 16; + /* Convert background color */ + bgcolor = freerdp_color_convert_var(bgcolor, + context->instance->settings->color_depth, 32, + ((rdp_freerdp_context*) context)->clrconv); - /* Create glyph surface and cairo instance */ - guac_client_data->glyph_surface = cairo_image_surface_create( - CAIRO_FORMAT_RGB24, width, height); + /* Fill background */ + cairo_rectangle(guac_client_data->glyph_cairo, + x, y, width, height); - guac_client_data->glyph_cairo = cairo_create( - guac_client_data->glyph_surface); + cairo_set_source_rgb(guac_client_data->glyph_cairo, + ( bgcolor & 0x0000FF ) / 255.0, + ((bgcolor & 0x00FF00) >> 8 ) / 255.0, + ((bgcolor & 0xFF0000) >> 16) / 255.0); - /* Fill with color */ - cairo_set_source_rgb(guac_client_data->glyph_cairo, - guac_client_data->background.red / 255.0, - guac_client_data->background.green / 255.0, - guac_client_data->background.blue / 255.0); - - cairo_rectangle(guac_client_data->glyph_cairo, - 0, 0, width, height); + cairo_fill(guac_client_data->glyph_cairo); - cairo_fill(guac_client_data->glyph_cairo); + } /* Prepare for glyph drawing */ cairo_set_source_rgb(guac_client_data->glyph_cairo, - guac_client_data->foreground.red / 255.0, - guac_client_data->foreground.green / 255.0, - guac_client_data->foreground.blue / 255.0); + ( fgcolor & 0x0000FF ) / 255.0, + ((fgcolor & 0x00FF00) >> 8 ) / 255.0, + ((fgcolor & 0xFF0000) >> 16) / 255.0); } @@ -178,14 +172,26 @@ void guac_rdp_glyph_enddraw(rdpContext* context, rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data; const guac_layer* current_layer = ((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); + + /* 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 layer */ guac_protocol_send_png(client->socket, GUAC_COMP_OVER, current_layer, x, y, - guac_client_data->glyph_surface); + surface); - /* Clean up cairo and glyph surface */ - cairo_destroy(guac_client_data->glyph_cairo); - cairo_surface_destroy(guac_client_data->glyph_surface); + /* Destroy surface */ + cairo_surface_destroy(surface); } -- 1.7.10.4