Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * Command queue is the only way to modify images. | 6 * Command queue is the only way to modify images. |
| 7 * Supports undo/redo. | 7 * Supports undo/redo. |
| 8 * Command execution is asynchronous (callback-based). | 8 * Command execution is asynchronous (callback-based). |
| 9 * | 9 * |
| 10 * @param {Document} document Document to create canvases in. | 10 * @param {Document} document Document to create canvases in. |
| 11 * @param {HTMLCanvasElement} canvas The canvas with the original image. | 11 * @param {HTMLCanvasElement} canvas The canvas with the original image. |
| 12 * @param {function(callback)} saveFunction Function to save the image. | 12 * @param {function(callback)} saveFunction Function to save the image. |
| 13 * @constructor | 13 * @constructor |
| 14 */ | 14 */ |
| 15 function CommandQueue(document, canvas, saveFunction) { | 15 function CommandQueue(document, canvas, saveFunction) { |
| 16 this.document_ = document; | 16 this.document_ = document; |
| 17 this.undo_ = []; | 17 this.undo_ = []; |
| 18 this.redo_ = []; | 18 this.redo_ = []; |
| 19 this.subscribers_ = []; | 19 this.subscribers_ = []; |
| 20 | 20 |
| 21 this.baselineImage_ = canvas; | |
| 22 this.currentImage_ = canvas; | 21 this.currentImage_ = canvas; |
| 22 | |
| 23 this.baselineImage_ = document.createElement('canvas'); | |
| 24 this.baselineImage_.width = this.currentImage_.width; | |
| 25 this.baselineImage_.height = this.currentImage_.height; | |
| 26 var context = this.baselineImage_.getContext('2d'); | |
| 27 context.drawImage(this.currentImage_, 0, 0); | |
| 28 | |
| 23 this.previousImage_ = document.createElement('canvas'); | 29 this.previousImage_ = document.createElement('canvas'); |
| 30 this.previousImageAvailable_ = false; | |
| 24 | 31 |
| 25 this.saveFunction_ = saveFunction; | 32 this.saveFunction_ = saveFunction; |
| 26 | 33 |
| 27 this.busy_ = false; | 34 this.busy_ = false; |
| 28 | 35 |
| 29 this.UIContext_ = {}; | 36 this.UIContext_ = {}; |
| 30 } | 37 } |
| 31 | 38 |
| 32 /** | 39 /** |
| 33 * Attach the UI elements to the command queue. | 40 * Attach the UI elements to the command queue. |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 * @param {function} callback Completion callback. | 122 * @param {function} callback Completion callback. |
| 116 * @private | 123 * @private |
| 117 */ | 124 */ |
| 118 CommandQueue.prototype.doExecute_ = function(command, uiContext, callback) { | 125 CommandQueue.prototype.doExecute_ = function(command, uiContext, callback) { |
| 119 if (!this.currentImage_) | 126 if (!this.currentImage_) |
| 120 throw new Error('Cannot operate on null image'); | 127 throw new Error('Cannot operate on null image'); |
| 121 | 128 |
| 122 // Remember one previous image so that the first undo is as fast as possible. | 129 // Remember one previous image so that the first undo is as fast as possible. |
| 123 this.previousImage_.width = this.currentImage_.width; | 130 this.previousImage_.width = this.currentImage_.width; |
| 124 this.previousImage_.height = this.currentImage_.height; | 131 this.previousImage_.height = this.currentImage_.height; |
| 132 this.previousImageAvailable_ = true; | |
| 125 var context = this.previousImage_.getContext('2d'); | 133 var context = this.previousImage_.getContext('2d'); |
| 126 context.drawImage(this.currentImage_, 0, 0); | 134 context.drawImage(this.currentImage_, 0, 0); |
| 127 | 135 |
| 128 command.execute( | 136 command.execute( |
| 129 this.document_, | 137 this.document_, |
| 130 this.currentImage_, | 138 this.currentImage_, |
| 131 function(result, opt_delay) { | 139 function(result, opt_delay) { |
| 132 this.currentImage_ = result; | 140 this.currentImage_ = result; |
| 133 callback(opt_delay); | 141 callback(opt_delay); |
| 134 }.bind(this), | 142 }.bind(this), |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 172 this.redo_.push(command); | 180 this.redo_.push(command); |
| 173 | 181 |
| 174 var self = this; | 182 var self = this; |
| 175 | 183 |
| 176 function complete() { | 184 function complete() { |
| 177 var delay = command.revertView( | 185 var delay = command.revertView( |
| 178 self.currentImage_, self.UIContext_.imageView); | 186 self.currentImage_, self.UIContext_.imageView); |
| 179 self.commit_(delay); | 187 self.commit_(delay); |
| 180 } | 188 } |
| 181 | 189 |
| 182 if (this.previousImage_) { | 190 if (this.previousImageAvailable_) { |
| 191 console.log('TRYING, WITH: ' + this.previousImage_.width); | |
|
yoshiki
2013/03/11 05:21:59
nit: Can you remove this?
mtomasz
2013/03/11 05:44:56
Done.
| |
| 183 // First undo after an execute call. | 192 // First undo after an execute call. |
| 184 this.currentImage_.width = this.previousImage_.width; | 193 this.currentImage_.width = this.previousImage_.width; |
| 185 this.currentImage_.height = this.previousImage_.height; | 194 this.currentImage_.height = this.previousImage_.height; |
| 186 var context = this.currentImage_.getContext('2d'); | 195 var context = this.currentImage_.getContext('2d'); |
| 187 context.drawImage(this.previousImage_, 0, 0); | 196 context.drawImage(this.previousImage_, 0, 0); |
| 188 | 197 |
| 189 // Free memory. | 198 // Free memory. |
| 190 this.previousImage_.width = 0; | 199 this.previousImage_.width = 0; |
| 191 this.previousImage_.height = 0; | 200 this.previousImage_.height = 0; |
| 201 this.previousImageAvailable_ = false; | |
| 192 | 202 |
| 193 complete(); | 203 complete(); |
| 194 // TODO(kaznacheev) Consider recalculating previousImage_ right here | 204 // TODO(kaznacheev) Consider recalculating previousImage_ right here |
| 195 // by replaying the commands in the background. | 205 // by replaying the commands in the background. |
| 196 } else { | 206 } else { |
| 197 this.currentImage_ = this.baselineImage_; | 207 this.currentImage_.width = this.baselineImage_.width; |
| 208 this.currentImage_.height = this.baselineImage_.height; | |
| 209 var context = this.currentImage_.getContext('2d'); | |
| 210 context.drawImage(this.baselineImage_, 0, 0); | |
| 198 | 211 |
| 199 var replay = function(index) { | 212 var replay = function(index) { |
| 200 if (index < self.undo_.length) | 213 if (index < self.undo_.length) |
| 201 self.doExecute_(self.undo_[index], {}, replay.bind(null, index + 1)); | 214 self.doExecute_(self.undo_[index], {}, replay.bind(null, index + 1)); |
| 202 else { | 215 else { |
| 203 complete(); | 216 complete(); |
| 204 } | 217 } |
| 205 }; | 218 }; |
| 206 | 219 |
| 207 replay(0); | 220 replay(0); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 226 }; | 239 }; |
| 227 | 240 |
| 228 /** | 241 /** |
| 229 * Closes internal buffers. Call to ensure, that internal buffers are freed | 242 * Closes internal buffers. Call to ensure, that internal buffers are freed |
| 230 * as soon as possible. | 243 * as soon as possible. |
| 231 */ | 244 */ |
| 232 CommandQueue.prototype.close = function() { | 245 CommandQueue.prototype.close = function() { |
| 233 // Free memory used by the undo buffer. | 246 // Free memory used by the undo buffer. |
| 234 this.previousImage_.width = 0; | 247 this.previousImage_.width = 0; |
| 235 this.previousImage_.height = 0; | 248 this.previousImage_.height = 0; |
| 249 this.previousImageAvailable_ = false; | |
| 250 | |
| 251 this.baselineImage_.width = 0; | |
| 252 this.baselineImage_.height = 0; | |
| 236 }; | 253 }; |
| 237 | 254 |
| 238 /** | 255 /** |
| 239 * Command object encapsulates an operation on an image and a way to visualize | 256 * Command object encapsulates an operation on an image and a way to visualize |
| 240 * its result. | 257 * its result. |
| 241 * | 258 * |
| 242 * @param {string} name Command name. | 259 * @param {string} name Command name. |
| 243 * @constructor | 260 * @constructor |
| 244 */ | 261 */ |
| 245 function Command(name) { | 262 function Command(name) { |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 421 | 438 |
| 422 function onProgressInvisible(updatedRow, rowCount) { | 439 function onProgressInvisible(updatedRow, rowCount) { |
| 423 if (updatedRow == rowCount) { | 440 if (updatedRow == rowCount) { |
| 424 callback(result); | 441 callback(result); |
| 425 } | 442 } |
| 426 } | 443 } |
| 427 | 444 |
| 428 filter.applyByStrips(result, srcCanvas, this.filter_, | 445 filter.applyByStrips(result, srcCanvas, this.filter_, |
| 429 uiContext.imageView ? onProgressVisible : onProgressInvisible); | 446 uiContext.imageView ? onProgressVisible : onProgressInvisible); |
| 430 }; | 447 }; |
| OLD | NEW |