GUAC-236: Implement buffer resize.

This commit is contained in:
Michael Jumper 2016-02-27 10:07:55 -08:00
parent 696c3c3184
commit a0197ee2c2
2 changed files with 85 additions and 1 deletions

View File

@ -23,22 +23,86 @@
#include "config.h" #include "config.h"
#include "buffer.h" #include "buffer.h"
#include <cairo/cairo.h>
#include <stdlib.h> #include <stdlib.h>
guacenc_buffer* guacenc_buffer_alloc() { guacenc_buffer* guacenc_buffer_alloc() {
return calloc(1, sizeof(guacenc_buffer)); return calloc(1, sizeof(guacenc_buffer));
} }
/**
* Frees the underlying image data, surface, and graphics context of the given
* buffer, marking each as unallocated.
*
* @param buffer
* The guacenc_buffer whose image data, surface, and graphics context
* should be freed.
*/
static void guacenc_buffer_free_image(guacenc_buffer* buffer) {
/* Free graphics context */
if (buffer->cairo != NULL) {
cairo_destroy(buffer->cairo);
buffer->cairo = NULL;
}
/* Free Cairo surface */
if (buffer->surface != NULL) {
cairo_surface_destroy(buffer->surface);
buffer->surface = NULL;
}
/* Free image data (previously wrapped by Cairo surface */
free(buffer->image);
buffer->image = NULL;
}
void guacenc_buffer_free(guacenc_buffer* buffer) { void guacenc_buffer_free(guacenc_buffer* buffer) {
guacenc_buffer_free_image(buffer);
free(buffer); free(buffer);
} }
int guacenc_buffer_resize(guacenc_buffer* buffer, int width, int height) { int guacenc_buffer_resize(guacenc_buffer* buffer, int width, int height) {
/* STUB */ /* Simply deallocate if new image has absolutely no pixels */
if (width == 0 || height == 0) {
guacenc_buffer_free_image(buffer);
buffer->width = width; buffer->width = width;
buffer->height = height; buffer->height = height;
buffer->stride = 0;
return 0;
}
/* Allocate data for new image */
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
unsigned char* image = calloc(1, stride*height);
/* Wrap data in surface */
cairo_surface_t* surface = cairo_image_surface_create_for_data(image,
CAIRO_FORMAT_ARGB32, width, height, stride);
/* Obtain graphics context of new surface */
cairo_t* cairo = cairo_create(surface);
/* Copy old surface, if defined */
if (buffer->surface != NULL) {
cairo_set_source_surface(cairo, buffer->surface, 0, 0);
cairo_paint(cairo);
cairo_set_source_rgba(cairo, 0.0, 0.0, 0.0, 1.0);
}
/* Update properties */
buffer->width = width;
buffer->height = height;
buffer->stride = stride;
/* Replace old image */
guacenc_buffer_free_image(buffer);
buffer->image = image;
buffer->surface = surface;
buffer->cairo = cairo;
return 0; return 0;

View File

@ -25,6 +25,8 @@
#include "config.h" #include "config.h"
#include <cairo/cairo.h>
/** /**
* The image and size storage for either a buffer (a Guacamole layer with a * The image and size storage for either a buffer (a Guacamole layer with a
* negative index) or a layer (a Guacamole layer with a non-negative index). * negative index) or a layer (a Guacamole layer with a non-negative index).
@ -46,6 +48,24 @@ typedef struct guacenc_buffer {
*/ */
int stride; int stride;
/**
* The underlying image data of this surface. If the width or height of
* this surface are 0, this will be NULL.
*/
unsigned char* image;
/**
* The Cairo surface wrapping the underlying image data of this surface. If
* the width or height of this surface are 0, this will be NULL.
*/
cairo_surface_t* surface;
/**
* The current graphics context of the Cairo surface. If the width or
* height of this surface are 0, this will be NULL.
*/
cairo_t* cairo;
} guacenc_buffer; } guacenc_buffer;
/** /**