Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 * @fileoverview Puts text on a braille display. | 6 * @fileoverview Puts text on a braille display. |
| 7 * | 7 * |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 goog.provide('cvox.BrailleDisplayManager'); | 10 goog.provide('cvox.BrailleDisplayManager'); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 this.realDisplayState_ = this.displayState_; | 68 this.realDisplayState_ = this.displayState_; |
| 69 | 69 |
| 70 translatorManager.addChangeListener(function() { | 70 translatorManager.addChangeListener(function() { |
| 71 this.translateContent_(this.content_, this.expansionType_); | 71 this.translateContent_(this.content_, this.expansionType_); |
| 72 }.bind(this)); | 72 }.bind(this)); |
| 73 | 73 |
| 74 chrome.storage.onChanged.addListener(function(changes, area) { | 74 chrome.storage.onChanged.addListener(function(changes, area) { |
| 75 if (area == 'local' && 'brailleWordWrap' in changes) { | 75 if (area == 'local' && 'brailleWordWrap' in changes) { |
| 76 this.updatePanStrategy_(changes.brailleWordWrap.newValue); | 76 this.updatePanStrategy_(changes.brailleWordWrap.newValue); |
| 77 } | 77 } |
| 78 if (area == 'local' && ('virtualBrailleRows' in changes || | |
|
dmazzoni
2016/12/05 17:29:40
This should probably be part of the previous chang
ultimatedbz
2016/12/05 19:37:38
Done.
| |
| 79 'virtualBrailleColumns' in changes)) { | |
| 80 this.onCaptionsStateChanged_(); | |
| 81 } | |
| 78 }.bind(this)); | 82 }.bind(this)); |
| 79 chrome.storage.local.get({brailleWordWrap: true}, function(items) { | 83 chrome.storage.local.get({brailleWordWrap: true}, function(items) { |
| 80 this.updatePanStrategy_(items.brailleWordWrap); | 84 this.updatePanStrategy_(items.brailleWordWrap); |
| 81 }.bind(this)); | 85 }.bind(this)); |
| 82 | 86 |
| 83 cvox.BrailleCaptionsBackground.init(goog.bind( | 87 cvox.BrailleCaptionsBackground.init(goog.bind( |
| 84 this.onCaptionsStateChanged_, this)); | 88 this.onCaptionsStateChanged_, this)); |
| 85 if (goog.isDef(chrome.brailleDisplayPrivate)) { | 89 if (goog.isDef(chrome.brailleDisplayPrivate)) { |
| 86 var onDisplayStateChanged = goog.bind(this.refreshDisplayState_, this); | 90 var onDisplayStateChanged = goog.bind(this.refreshDisplayState_, this); |
| 87 chrome.brailleDisplayPrivate.getDisplayState(onDisplayStateChanged); | 91 chrome.brailleDisplayPrivate.getDisplayState(onDisplayStateChanged); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 112 * of the display content is expanded when translating to braille. | 116 * of the display content is expanded when translating to braille. |
| 113 * (See {@code cvox.ExpandingBrailleTranslator}). | 117 * (See {@code cvox.ExpandingBrailleTranslator}). |
| 114 */ | 118 */ |
| 115 cvox.BrailleDisplayManager.prototype.setContent = function( | 119 cvox.BrailleDisplayManager.prototype.setContent = function( |
| 116 content, expansionType) { | 120 content, expansionType) { |
| 117 this.translateContent_(content, expansionType); | 121 this.translateContent_(content, expansionType); |
| 118 }; | 122 }; |
| 119 | 123 |
| 120 | 124 |
| 121 /** | 125 /** |
| 126 * Takes a imageDataUrl and displays it in braille onto the physical braille | |
|
dmazzoni
2016/12/05 17:29:40
Takes an image, in the form of a data url,
ultimatedbz
2016/12/05 19:32:00
Done.
| |
| 127 * display and the virtual braille captions display. | |
| 128 * @param {!string} imageUrl The imageDataUrl of the image to display. | |
|
dmazzoni
2016/12/05 17:29:40
Same, "The image, in the form of a data url" or so
ultimatedbz
2016/12/05 19:32:01
Done.
| |
| 129 */ | |
| 130 cvox.BrailleDisplayManager.prototype.setImageContent = function(imageUrl) { | |
| 131 var rows = this.displayState_.textRowCount; | |
| 132 var columns = this.displayState_.textColumnCount; | |
| 133 var imageDataUrl = imageUrl; | |
| 134 var imgElement = document.createElement('img'); | |
| 135 imgElement.src = imageDataUrl; | |
| 136 var c1 = document.createElement('canvas'); | |
|
dmazzoni
2016/12/05 17:29:40
var canvas
ultimatedbz
2016/12/05 19:32:01
Done.
| |
| 137 var context = c1.getContext('2d'); | |
| 138 c1.width = imgElement.width; | |
| 139 c1.height = imgElement.height; | |
| 140 context.drawImage(imgElement, 0, 0); | |
| 141 var originalImageData = context.getImageData(0, 0, c1.width, c1.height); | |
| 142 var originalData = originalImageData.data; | |
| 143 | |
| 144 // Convert image to black and white. | |
| 145 var c2 = document.createElement('canvas'); | |
|
dmazzoni
2016/12/05 17:29:40
You probably don't need two canvases for this, rig
ultimatedbz
2016/12/05 19:32:01
Done.
| |
| 146 var context2 = c2.getContext('2d'); | |
| 147 c2.width = imgElement.width; | |
| 148 c2.height = imgElement.height; | |
| 149 var blackWhiteData = []; | |
| 150 for (var i = 0; i < originalData.length; i += 4) { | |
| 151 // If the alpha value is transparent (less than 20) or the pixel is | |
| 152 // white(over 600), don't show. | |
| 153 var value = (originalData[i] + | |
| 154 originalData[i + 1] + | |
| 155 originalData[i + 2] > 200 * 3) || | |
| 156 (originalData[i + 3]) < 20 ? 0 : 255; | |
| 157 blackWhiteData[i] = value; | |
| 158 blackWhiteData[i + 1] = value; | |
| 159 blackWhiteData[i + 2] = value; | |
| 160 } | |
| 161 var blackWhiteImageData = context2.getImageData(0, 0, c2.width, c2.height); | |
| 162 blackWhiteImageData.data = blackWhiteData; | |
| 163 context2.putImageData(blackWhiteImageData, 0, 0, 0, 0, c2.width, c2.height); | |
| 164 | |
| 165 // Scaled down to braille dimensions. | |
|
dmazzoni
2016/12/05 17:29:40
I think it'd look better to rescale first, then
co
ultimatedbz
2016/12/05 19:32:01
That's awesome! You can actually specify how big y
| |
| 166 var c3 = document.createElement('canvas'); | |
| 167 var context3 = c3.getContext('2d'); | |
| 168 c3.width = columns * 2; | |
| 169 c3.height = rows * 4; | |
| 170 var imageData3 = context3.createImageData(c3.width, c3.height); | |
| 171 var data3 = imageData3.data; | |
| 172 var data = blackWhiteData; | |
| 173 var xScale = c2.width / c3.width; | |
| 174 var yScale = c2.height / c3.height; | |
| 175 for (var i = 0; i < c3.height; i++) { | |
| 176 for (var j = 0; j < c3.width; j++) { | |
| 177 var newX = Math.floor(j * xScale); | |
| 178 var newY = Math.floor(i * yScale); | |
| 179 var index = newX * 4 + newY * 4 * c2.width; | |
| 180 var index3 = i * 4 * c3.width + 4 * j; | |
| 181 | |
| 182 data3[index3] = data[index]; | |
| 183 data3[index3 + 1] = data[index + 1]; | |
| 184 data3[index3 + 2] = data[index + 2]; | |
| 185 data3[index3 + 3] = data[index + 3]; | |
| 186 } | |
| 187 } | |
| 188 context3.putImageData(imageData3, 0, 0); | |
| 189 | |
| 190 // Covert to Braille. | |
|
dmazzoni
2016/12/05 17:29:40
Convert
ultimatedbz
2016/12/05 19:32:01
Done.
| |
| 191 var buf = new ArrayBuffer(rows * columns); | |
| 192 var view = new Uint8Array(buf); | |
| 193 var dot1 = 0x1; | |
| 194 var dot2 = 0x2; | |
| 195 var dot3 = 0x4; | |
| 196 var dot4 = 0x8; | |
| 197 var dot5 = 0x10; | |
| 198 var dot6 = 0x20; | |
| 199 var dot7 = 0x40; | |
| 200 var dot8 = 0x80; | |
| 201 | |
| 202 for (var i = 0; i < rows; i++) { | |
| 203 for (var j = 0; j < columns; j++) { | |
| 204 //Index in braille array | |
| 205 var index = i * columns + j; | |
| 206 | |
| 207 view[index] = 0; | |
| 208 if (data3[(i * columns * 4 + j) * 2 * 4] == 255) | |
|
dmazzoni
2016/12/05 17:29:40
I'd do something like this:
coordsToBrailleDot[0]
ultimatedbz
2016/12/05 19:32:01
This was really clever. On top of this, I made som
| |
| 209 view[index] += dot1; | |
| 210 if (data3[(i * columns * 4 + j + columns) * 2 * 4] == 255) | |
| 211 view[index] += dot2; | |
| 212 if (data3[(i * columns * 4 + j + 2 * columns) * 2 * 4] == 255) | |
| 213 view[index] += dot3; | |
| 214 if (data3[(i * columns * 4 + j + 3 * columns) * 2 * 4] == 255) | |
| 215 view[index] += dot7; | |
| 216 | |
| 217 if (data3[((i * columns * 4 + j) * 2 + 1) * 4] == 255) | |
| 218 view[index] += dot4; | |
| 219 if (data3[((i * columns * 4 + j + columns) * 2 + 1) * 4] == 255) | |
| 220 view[index] += dot5; | |
| 221 if (data3[((i * columns * 4 + j + 2 * columns) * 2 + 1) * 4] == 255) | |
| 222 view[index] += dot6; | |
| 223 if (data3[((i * columns * 4 + j + 3 * columns) * 2 + 1) * 4] == 255) | |
| 224 view[index] += dot8; | |
| 225 } | |
| 226 } | |
| 227 | |
| 228 if (!this.displayState_.available) { | |
|
dmazzoni
2016/12/05 17:29:40
Put this check at the top
ultimatedbz
2016/12/05 19:32:01
Done.
| |
| 229 return; | |
| 230 } | |
| 231 if (this.realDisplayState_.available) { | |
| 232 chrome.brailleDisplayPrivate.writeDots(buf, buf.byteLength, 1); | |
| 233 } | |
| 234 if (cvox.BrailleCaptionsBackground.isEnabled()) { | |
| 235 cvox.BrailleCaptionsBackground.setImageContent(buf, rows, columns); | |
| 236 } | |
| 237 }; | |
| 238 | |
| 239 | |
| 240 /** | |
| 122 * Sets the command listener. When a command is invoked, the listener will be | 241 * Sets the command listener. When a command is invoked, the listener will be |
| 123 * called with the BrailleKeyEvent corresponding to the command and the content | 242 * called with the BrailleKeyEvent corresponding to the command and the content |
| 124 * that was present on the display when the command was invoked. The content | 243 * that was present on the display when the command was invoked. The content |
| 125 * is guaranteed to be identical to an object previously used as the parameter | 244 * is guaranteed to be identical to an object previously used as the parameter |
| 126 * to cvox.BrailleDisplayManager.setContent, or null if no content was set. | 245 * to cvox.BrailleDisplayManager.setContent, or null if no content was set. |
| 127 * @param {function(!cvox.BrailleKeyEvent, !cvox.NavBraille)} func The listener. | 246 * @param {function(!cvox.BrailleKeyEvent, !cvox.NavBraille)} func The listener. |
| 128 */ | 247 */ |
| 129 cvox.BrailleDisplayManager.prototype.setCommandListener = function(func) { | 248 cvox.BrailleDisplayManager.prototype.setCommandListener = function(func) { |
| 130 this.commandListener_ = func; | 249 this.commandListener_ = func; |
| 131 }; | 250 }; |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 }; | 481 }; |
| 363 | 482 |
| 364 /** | 483 /** |
| 365 * @param {boolean} wordWrap | 484 * @param {boolean} wordWrap |
| 366 * @private | 485 * @private |
| 367 */ | 486 */ |
| 368 cvox.BrailleDisplayManager.prototype.updatePanStrategy_ = function(wordWrap) { | 487 cvox.BrailleDisplayManager.prototype.updatePanStrategy_ = function(wordWrap) { |
| 369 this.panStrategy_.setPanStrategy(wordWrap); | 488 this.panStrategy_.setPanStrategy(wordWrap); |
| 370 this.refresh_(); | 489 this.refresh_(); |
| 371 }; | 490 }; |
| OLD | NEW |