GUAC-236: Ensure buffers are resized to fit draw operations (unless they are within layers).
This commit is contained in:
parent
83beccf7e4
commit
ba9c1a2efd
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include <cairo/cairo.h>
|
#include <cairo/cairo.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
guacenc_buffer* guacenc_buffer_alloc() {
|
guacenc_buffer* guacenc_buffer_alloc() {
|
||||||
@ -115,3 +116,24 @@ int guacenc_buffer_resize(guacenc_buffer* buffer, int width, int height) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int guacenc_buffer_fit(guacenc_buffer* buffer, int x, int y) {
|
||||||
|
|
||||||
|
/* Increase width to fit X (if necessary) */
|
||||||
|
int new_width = buffer->width;
|
||||||
|
if (new_width < x+1)
|
||||||
|
new_width = x+1;
|
||||||
|
|
||||||
|
/* Increase height to fit Y (if necessary) */
|
||||||
|
int new_height = buffer->height;
|
||||||
|
if (new_height < y+1)
|
||||||
|
new_height = y+1;
|
||||||
|
|
||||||
|
/* Resize buffer if size needs to change to fit X/Y coordinate */
|
||||||
|
if (new_width != buffer->width || new_height != buffer->height)
|
||||||
|
return guacenc_buffer_resize(buffer, new_width, new_height);
|
||||||
|
|
||||||
|
/* No change necessary */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -27,12 +27,20 @@
|
|||||||
|
|
||||||
#include <cairo/cairo.h>
|
#include <cairo/cairo.h>
|
||||||
|
|
||||||
|
#include <stdbool.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).
|
||||||
*/
|
*/
|
||||||
typedef struct guacenc_buffer {
|
typedef struct guacenc_buffer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this buffer should be automatically resized to fit any draw
|
||||||
|
* operation.
|
||||||
|
*/
|
||||||
|
bool autosize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The width of this buffer or layer, in pixels.
|
* The width of this buffer or layer, in pixels.
|
||||||
*/
|
*/
|
||||||
@ -107,5 +115,26 @@ void guacenc_buffer_free(guacenc_buffer* buffer);
|
|||||||
*/
|
*/
|
||||||
int guacenc_buffer_resize(guacenc_buffer* buffer, int width, int height);
|
int guacenc_buffer_resize(guacenc_buffer* buffer, int width, int height);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resizes the given buffer as necessary to contain at the given X/Y
|
||||||
|
* coordinate, allocating or freeing memory as necessary, and updating the
|
||||||
|
* buffer's width, height, and stride properties. If the buffer already
|
||||||
|
* contains the given coordinate, this function has no effect.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* The buffer to resize.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* The X coordinate to ensure is within the buffer.
|
||||||
|
*
|
||||||
|
* @param y
|
||||||
|
* The Y coordinate to ensure is within the buffer.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* Zero if the resize operation is successful or no resize was performed,
|
||||||
|
* non-zero if the resize operation failed.
|
||||||
|
*/
|
||||||
|
int guacenc_buffer_fit(guacenc_buffer* buffer, int x, int y);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -132,18 +132,19 @@ int guacenc_image_stream_end(guacenc_image_stream* stream,
|
|||||||
if (surface == NULL)
|
if (surface == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/* Get surface dimensions */
|
||||||
|
int width = cairo_image_surface_get_width(surface);
|
||||||
|
int height = cairo_image_surface_get_height(surface);
|
||||||
|
|
||||||
|
/* Expand the buffer as necessary to fit the draw operation */
|
||||||
|
if (buffer->autosize)
|
||||||
|
guacenc_buffer_fit(buffer, stream->x + width, stream->y + height);
|
||||||
|
|
||||||
/* Draw surface to buffer */
|
/* Draw surface to buffer */
|
||||||
if (buffer->cairo != NULL) {
|
if (buffer->cairo != NULL) {
|
||||||
|
|
||||||
/* Get surface dimensions */
|
|
||||||
int width = cairo_image_surface_get_width(surface);
|
|
||||||
int height = cairo_image_surface_get_height(surface);
|
|
||||||
|
|
||||||
/* Paint surface contents to buffer */
|
|
||||||
cairo_set_source_surface(buffer->cairo, surface, stream->x, stream->y);
|
cairo_set_source_surface(buffer->cairo, surface, stream->x, stream->y);
|
||||||
cairo_rectangle(buffer->cairo, stream->x, stream->y, width, height);
|
cairo_rectangle(buffer->cairo, stream->x, stream->y, width, height);
|
||||||
cairo_fill(buffer->cairo);
|
cairo_fill(buffer->cairo);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_surface_destroy(surface);
|
cairo_surface_destroy(surface);
|
||||||
|
@ -57,6 +57,10 @@ int guacenc_handle_copy(guacenc_display* display, int argc, char** argv) {
|
|||||||
if (dst == NULL)
|
if (dst == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/* Expand the destination buffer as necessary to fit the draw operation */
|
||||||
|
if (dst->autosize)
|
||||||
|
guacenc_buffer_fit(dst, dx + width, dy + height);
|
||||||
|
|
||||||
/* Copy rectangle from source to destination */
|
/* Copy rectangle from source to destination */
|
||||||
if (src->surface != NULL && dst->cairo != NULL) {
|
if (src->surface != NULL && dst->cairo != NULL) {
|
||||||
cairo_set_operator(dst->cairo, guacenc_display_cairo_operator(mask));
|
cairo_set_operator(dst->cairo, guacenc_display_cairo_operator(mask));
|
||||||
|
@ -50,6 +50,10 @@ int guacenc_handle_rect(guacenc_display* display, int argc, char** argv) {
|
|||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/* Expand the buffer as necessary to fit the draw operation */
|
||||||
|
if (buffer->autosize)
|
||||||
|
guacenc_buffer_fit(buffer, x + width, y + height);
|
||||||
|
|
||||||
/* Set path to rectangle */
|
/* Set path to rectangle */
|
||||||
if (buffer->cairo != NULL)
|
if (buffer->cairo != NULL)
|
||||||
cairo_rectangle(buffer->cairo, x, y, width, height);
|
cairo_rectangle(buffer->cairo, x, y, width, height);
|
||||||
|
Loading…
Reference in New Issue
Block a user