diff --git a/guacamole-common-js/src/main/resources/guacamole.js b/guacamole-common-js/src/main/resources/guacamole.js index 371ba73e6..f4cf49604 100644 --- a/guacamole-common-js/src/main/resources/guacamole.js +++ b/guacamole-common-js/src/main/resources/guacamole.js @@ -154,7 +154,7 @@ Guacamole.Client = function(display, tunnel) { // Create buffer if necessary if (buffer == null) { buffer = new Guacamole.Layer(0, 0); - buffer.setAutosize(1); + buffer.autosize = 1; buffers[index] = buffer; } diff --git a/guacamole-common-js/src/main/resources/layer.js b/guacamole-common-js/src/main/resources/layer.js index 16fef960a..01acafbe0 100644 --- a/guacamole-common-js/src/main/resources/layer.js +++ b/guacamole-common-js/src/main/resources/layer.js @@ -37,9 +37,11 @@ var Guacamole = Guacamole || {}; */ Guacamole.Layer = function(width, height) { + // Reference to this Layer var layer = this; - // Off-screen buffer + // Off-screen buffer (canvas element) and corresponding + // context. var display = document.createElement("canvas"); var displayContext = display.getContext("2d"); @@ -51,6 +53,14 @@ Guacamole.Layer = function(width, height) { return display; }; + /** + * Resizes the canvas element backing this Layer without testing the + * new size. This function should only be used internally. + * + * @private + * @param {Number} newWidth The new width to assign to this Layer. + * @param {Number} newHeight The new height to assign to this Layer. + */ function resize(newWidth, newHeight) { display.style.position = "absolute"; display.style.left = "0px"; @@ -76,6 +86,22 @@ Guacamole.Layer = function(width, height) { resize(newWidth, newHeight); }; + /** + * Given the X and Y coordinates of the upper-left corner of a rectangle + * and the rectangle's width and height, resize the backing canvas element + * as necessary to ensure that the rectangle fits within the canvas + * element's coordinate space. This function will only make the canvas + * larger. If the rectangle already fits within the canvas element's + * coordinate space, the canvas is left unchanged. + * + * @private + * @param {Number} x The X coordinate of the upper-left corner of the + * rectangle to fit. + * @param {Number} y The Y coordinate of the upper-left corner of the + * rectangle to fit. + * @param {Number} w The width of the the rectangle to fit. + * @param {Number} h The height of the the rectangle to fit. + */ function fitRect(x, y, w, h) { // Calculate bounds @@ -102,10 +128,31 @@ Guacamole.Layer = function(width, height) { } + // Initialize canvas dimensions resize(width, height); + /** + * Set to true if this Layer should resize itself to accomodate the + * dimensions of any drawing operation, and false (the default) otherwise. + * + * Note that setting this property takes effect immediately, and thus may + * take effect on operations that were started in the past but have not + * yet completed. If you wish the setting of this flag to only modify + * future operations, you will need to make the setting of this flag an + * operation with sync(). + * + * @example + * // Set autosize to true for all future operations + * layer.sync(function() { + * layer.autosize = true; + * }); + * + * @type Boolean + * @default false + */ + this.autosize = false; + var updates = new Array(); - var autosize = 0; function Update(updateHandler) { @@ -123,10 +170,6 @@ Guacamole.Layer = function(width, height) { } - this.setAutosize = function(flag) { - autosize = flag; - }; - function reserveJob(handler) { // If no pending updates, just call (if available) and exit @@ -154,11 +197,25 @@ Guacamole.Layer = function(width, height) { } + /** + * Returns whether this Layer is ready. A Layer is ready if it has no + * pending operations and no operations in-progress. + * + * @returns {Boolean} true if this Layer is ready, false otherwise. + */ this.isReady = function() { return updates.length == 0; }; - + /** + * Draws the specified image at the given coordinates. The image specified + * must already be loaded. + * + * @param {Number} x The destination X coordinate. + * @param {Number} y The destination Y coordinate. + * @param {Image} image The image to draw. Note that this is an Image + * object - not a URL. + */ this.drawImage = function(x, y, image) { reserveJob(function() { if (autosize != 0) fitRect(x, y, image.width, image.height); @@ -166,7 +223,15 @@ Guacamole.Layer = function(width, height) { }); }; - + /** + * Draws the image at the specified URL at the given coordinates. The image + * will be loaded automatically, and this and any future operations will + * wait for the image to finish loading. + * + * @param {Number} x The destination X coordinate. + * @param {Number} y The destination Y coordinate. + * @param {String} url The URL of the image to draw. + */ this.draw = function(x, y, url) { var update = reserveJob(null); @@ -198,11 +263,32 @@ Guacamole.Layer = function(width, height) { reserveJob(handler); }; - this.copyRect = function(srcLayer, srcx, srcy, w, h, x, y) { + /** + * Copy a rectangle of image data from one Layer to this Layer. This + * operation will copy exactly the image data that will be drawn once all + * operations of the source Layer that were pending at the time this + * function was called are complete. This operation will not alter the + * size of the source Layer even if its autosize property is set to true. + * + * @param {Guacamole.Layer} srcLayer The Layer to copy image data from. + * @param {Number} srcx The X coordinate of the upper-left corner of the + * rectangle within the source Layer's coordinate + * space to copy data from. + * @param {Number} srcy The Y coordinate of the upper-left corner of the + * rectangle within the source Layer's coordinate + * space to copy data from. + * @param {Number} srcw The width of the rectangle within the source Layer's + * coordinate space to copy data from. + * @param {Number} srch The height of the rectangle within the source + * Layer's coordinate space to copy data from. + * @param {Number} x The destination X coordinate. + * @param {Number} y The destination Y coordinate. + */ + this.copyRect = function(srcLayer, srcx, srcy, srcw, srch, x, y) { function doCopyRect() { - if (autosize != 0) fitRect(x, y, w, h); - displayContext.drawImage(srcLayer, srcx, srcy, w, h, x, y, w, h); + if (autosize != 0) fitRect(x, y, srcw, srch); + displayContext.drawImage(srcLayer, srcx, srcy, srcw, srch, x, y, srcw, srch); } // If we ARE the source layer, no need to sync.