Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Side by Side Diff: chrome/browser/resources/chromeos/chromevox/braille/braille_display_manager.js

Issue 2703663002: Display images in multiline Braille (Closed)
Patch Set: Use freeze / thaw Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 */ 50 */
51 this.commandListener_ = function() {}; 51 this.commandListener_ = function() {};
52 /** 52 /**
53 * Current display state to show in the Virtual Braille Captions display. 53 * Current display state to show in the Virtual Braille Captions display.
54 * This is different from realDisplayState_ if the braille captions feature 54 * This is different from realDisplayState_ if the braille captions feature
55 * is enabled and there is no hardware display connected. Otherwise, it is 55 * is enabled and there is no hardware display connected. Otherwise, it is
56 * the same object as realDisplayState_. 56 * the same object as realDisplayState_.
57 * @type {!cvox.BrailleDisplayState} 57 * @type {!cvox.BrailleDisplayState}
58 * @private 58 * @private
59 */ 59 */
60 this.displayState_ = {available: false, textRowCount: undefined, 60 this.displayState_ = {available: false, textRowCount: 0,
61 textColumnCount: undefined}; 61 textColumnCount: 0};
62 /** 62 /**
63 * State reported from the chrome api, reflecting a real hardware 63 * State reported from the chrome api, reflecting a real hardware
64 * display. 64 * display.
65 * @type {!cvox.BrailleDisplayState} 65 * @type {!cvox.BrailleDisplayState}
66 * @private 66 * @private
67 */ 67 */
68 this.realDisplayState_ = this.displayState_; 68 this.realDisplayState_ = this.displayState_;
69 69
70 /**
71 * @type {boolean} True if we're currently displaying an image, false if
72 * we're displaying text.
David Tseng 2017/02/24 05:39:46 No longer needed.
dmazzoni 2017/02/27 06:56:24 Done.
73 * @private
74 */
75 this.displayingImage_ = false;
76
70 translatorManager.addChangeListener(function() { 77 translatorManager.addChangeListener(function() {
71 this.translateContent_(this.content_, this.expansionType_); 78 this.translateContent_(this.content_, this.expansionType_);
72 }.bind(this)); 79 }.bind(this));
73 80
74 chrome.storage.onChanged.addListener(function(changes, area) { 81 chrome.storage.onChanged.addListener(function(changes, area) {
75 if (area == 'local' && 'brailleWordWrap' in changes) { 82 if (area == 'local' && 'brailleWordWrap' in changes) {
76 this.updatePanStrategy_(changes.brailleWordWrap.newValue); 83 this.updatePanStrategy_(changes.brailleWordWrap.newValue);
77 } 84 }
78 if (area == 'local' && ('virtualBrailleRows' in changes || 85 if (area == 'local' && ('virtualBrailleRows' in changes ||
79 'virtualBrailleColumns' in changes)) { 86 'virtualBrailleColumns' in changes)) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 118
112 /** 119 /**
113 * @param {!cvox.NavBraille} content Content to send to the braille display. 120 * @param {!cvox.NavBraille} content Content to send to the braille display.
114 * @param {!cvox.ExpandingBrailleTranslator.ExpansionType} expansionType 121 * @param {!cvox.ExpandingBrailleTranslator.ExpansionType} expansionType
115 * If the text has a {@code ValueSpan}, this indicates how that part 122 * If the text has a {@code ValueSpan}, this indicates how that part
116 * of the display content is expanded when translating to braille. 123 * of the display content is expanded when translating to braille.
117 * (See {@code cvox.ExpandingBrailleTranslator}). 124 * (See {@code cvox.ExpandingBrailleTranslator}).
118 */ 125 */
119 cvox.BrailleDisplayManager.prototype.setContent = function( 126 cvox.BrailleDisplayManager.prototype.setContent = function(
120 content, expansionType) { 127 content, expansionType) {
128 this.displayingImage_ = false;
121 this.translateContent_(content, expansionType); 129 this.translateContent_(content, expansionType);
122 }; 130 };
123 131
124 132
125 /** 133 /**
134 * Takes an image, in the form of a data url, and displays it in braille
David Tseng 2017/02/24 05:39:45 Would be helpful to include a note of how this is
135 * onto the physical braille display and the virtual braille captions display.
136 * @param {!string} imageUrl The image, in the form of a data url.
137 */
138 cvox.BrailleDisplayManager.prototype.setImageContent = function(imageUrl) {
139 this.displayingImage_ = true;
David Tseng 2017/02/24 05:39:45 Move this below the check for availability.
dmazzoni 2017/02/27 06:56:23 Done.
140 if (!this.displayState_.available) {
141 return;
142 }
143
144 var rows = this.displayState_.textRowCount;
145 var columns = this.displayState_.textColumnCount;
146 var imageDataUrl = imageUrl;
147 var imgElement = document.createElement('img');
148 imgElement.src = imageDataUrl;
149 imgElement.onload = (function() {
150 var canvas = document.createElement('canvas');
151 var context = canvas.getContext('2d');
152 canvas.width = columns * 2;
153 canvas.height = rows * 4;
David Tseng 2017/02/24 05:39:45 It would be helpful to name these constants or to
dmazzoni 2017/02/27 06:56:24 Done.
154 context.drawImage(imgElement, 0, 0, canvas.width, canvas.height);
155 var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
156 var data = imageData.data;
157 var outputData = [];
158
159 // Convert image to black and white.
160 for (var i = 0; i < data.length; i += 4) {
161 // Show if the alpha value is visible (above 20) and the pixel is not
David Tseng 2017/02/24 05:39:46 This doesn't seem to match the below check. They'r
dmazzoni 2017/02/27 06:56:23 Cleaned up, and also made it more easy to justify
162 // white (under 600).
163 var show = (data[i] +
David Tseng 2017/02/24 05:39:46 Name each of these offsets (e.g. i + RED_OFFSET, i
dmazzoni 2017/02/27 06:56:23 I did it slightly differently but should be just a
164 data[i + 1] +
165 data[i + 2] <= 200 * 3) &&
David Tseng 2017/02/24 05:39:45 600 please (so it matches the comment above) and b
dmazzoni 2017/02/27 06:56:23 Should be clear now, let me know.
166 (data[i + 3]) == 255;
167 outputData.push(show);
168 }
169
170 // Convert to Braille.
171 var buf = new ArrayBuffer(rows * columns);
David Tseng 2017/02/24 05:39:45 Maybe brailleBuff?
dmazzoni 2017/02/27 06:56:23 brailleBuf to match elsewhere in the file
172 var view = new Uint8Array(buf);
173 var coordsToBrailleDot = [0x1, 0x2, 0x4, 0x40, 0x8, 0x10, 0x20, 0x80];
David Tseng 2017/02/24 05:39:46 This is just static data; promote to a static clas
dmazzoni 2017/02/27 06:56:24 Done.
174 for (var i = 0; i < rows; i++) {
175 for (var j = 0; j < columns; j++) {
176 //Index in braille array
177 var index = i * columns + j;
David Tseng 2017/02/24 05:39:46 brailleIndex
dmazzoni 2017/02/27 06:56:23 Done.
178 view[index] = 0;
David Tseng 2017/02/24 05:39:46 Not need; ArrayBuffer contents are initialized to
dmazzoni 2017/02/27 06:56:24 Done.
179 for (var x = 0; x < 2; x++) {
David Tseng 2017/02/24 05:39:46 x is cell width so maybe brailleCellRow
dmazzoni 2017/02/27 06:56:24 Done.
180 for (var y = 0; y < 4; y++) {
David Tseng 2017/02/24 05:39:46 Use constants (see other comment).
dmazzoni 2017/02/27 06:56:23 Done.
181 if (outputData[((i * columns * 4 + j + y * columns) * 2 + x)])
David Tseng 2017/02/24 05:39:46 Can you distribute the index here and add a commen
dmazzoni 2017/02/27 06:56:23 Cleaned up, how's this?
182 view[index] += coordsToBrailleDot[x * 4 + y];
183 }
184 }
185 }
186 }
187
188 if (this.realDisplayState_.available) {
189 chrome.brailleDisplayPrivate.writeDots(
190 buf,
191 this.displayState_.textColumnCount,
192 this.displayState_.textRowCount);
193 }
194 if (cvox.BrailleCaptionsBackground.isEnabled()) {
195 cvox.BrailleCaptionsBackground.setImageContent(buf, rows, columns);
196 }
197 }).bind(this);
198 };
199
200
201 /**
126 * Sets the command listener. When a command is invoked, the listener will be 202 * Sets the command listener. When a command is invoked, the listener will be
127 * called with the BrailleKeyEvent corresponding to the command and the content 203 * called with the BrailleKeyEvent corresponding to the command and the content
128 * that was present on the display when the command was invoked. The content 204 * that was present on the display when the command was invoked. The content
129 * is guaranteed to be identical to an object previously used as the parameter 205 * is guaranteed to be identical to an object previously used as the parameter
130 * to cvox.BrailleDisplayManager.setContent, or null if no content was set. 206 * to cvox.BrailleDisplayManager.setContent, or null if no content was set.
131 * @param {function(!cvox.BrailleKeyEvent, !cvox.NavBraille)} func The listener. 207 * @param {function(!cvox.BrailleKeyEvent, !cvox.NavBraille)} func The listener.
132 */ 208 */
133 cvox.BrailleDisplayManager.prototype.setCommandListener = function(func) { 209 cvox.BrailleDisplayManager.prototype.setCommandListener = function(func) {
134 this.commandListener_ = func; 210 this.commandListener_ = func;
135 }; 211 };
136 212
137 213
138 /** 214 /**
139 * @param {!cvox.BrailleDisplayState} newState Display state reported 215 * @return {!cvox.BrailleDisplayState} The current display state.
140 * by the extension API. 216 */
217 cvox.BrailleDisplayManager.prototype.getDisplayState = function() {
218 return this.displayState_;
219 };
220
221
222 /**
223 * @param {{available: boolean, textRowCount: (number|undefined),
224 * textColumnCount: (number|undefined)}} newState Display state reported
225 * by the extension API. Note that the type is almost the same as
226 * cvox.BrailleDisplayState except that the extension API allows
227 * some fields to be undefined, while cvox.BrailleDisplayState does not.
141 * @private 228 * @private
142 */ 229 */
143 cvox.BrailleDisplayManager.prototype.refreshDisplayState_ = function( 230 cvox.BrailleDisplayManager.prototype.refreshDisplayState_ = function(
144 newState) { 231 newState) {
145 var oldColumnCount = this.displayState_.textColumnCount || 0; 232 var oldColumnCount = this.displayState_.textColumnCount || 0;
146 var oldRowCount = this.displayState_.textRowCount || 0; 233 var oldRowCount = this.displayState_.textRowCount || 0;
147 var processDisplayState = function(displayState) { 234 var processDisplayState = function(displayState) {
148 this.displayState_ = displayState; 235 this.displayState_ = displayState;
149 var newColumnCount = displayState.textColumnCount || 0; 236 var newColumnCount = displayState.textColumnCount || 0;
150 var newRowCount = displayState.textRowCount || 0; 237 var newRowCount = displayState.textRowCount || 0;
151 238
152 if (oldColumnCount != newColumnCount || oldRowCount != newRowCount) { 239 if (oldColumnCount != newColumnCount || oldRowCount != newRowCount) {
153 this.panStrategy_.setDisplaySize(newRowCount, newColumnCount); 240 this.panStrategy_.setDisplaySize(newRowCount, newColumnCount);
154 } 241 }
155 this.refresh_(); 242 this.refresh_();
156 }.bind(this); 243 }.bind(this);
157 this.realDisplayState_ = newState; 244 this.realDisplayState_ = {
245 available: newState.available,
246 textRowCount: newState.textRowCount || 0,
247 textColumnCount: newState.textColumnCount || 0
248 };
158 if (newState.available) { 249 if (newState.available) {
159 processDisplayState(newState); 250 processDisplayState(newState);
160 // Update the dimensions of the virtual braille captions display to those 251 // Update the dimensions of the virtual braille captions display to those
161 // of a real physical display when one is plugged in. 252 // of a real physical display when one is plugged in.
162 } else { 253 } else {
163 cvox.BrailleCaptionsBackground.getVirtualDisplayState(processDisplayState); 254 cvox.BrailleCaptionsBackground.getVirtualDisplayState(processDisplayState);
164 } 255 }
165 }; 256 };
166 257
167 258
168 /** 259 /**
169 * Called when the state of braille captions changes. 260 * Called when the state of braille captions changes.
170 * @private 261 * @private
171 */ 262 */
172 cvox.BrailleDisplayManager.prototype.onCaptionsStateChanged_ = function() { 263 cvox.BrailleDisplayManager.prototype.onCaptionsStateChanged_ = function() {
173 // Force reevaluation of the display state based on our stored real 264 // Force reevaluation of the display state based on our stored real
174 // hardware display state, meaning that if a real display is connected, 265 // hardware display state, meaning that if a real display is connected,
175 // that takes precedence over the state from the captions 'virtual' display. 266 // that takes precedence over the state from the captions 'virtual' display.
176 this.refreshDisplayState_(this.realDisplayState_); 267 this.refreshDisplayState_(this.realDisplayState_);
177 }; 268 };
178 269
179 270
180 /** 271 /**
181 * Refreshes what is shown on the physical braille display and the virtual 272 * Refreshes what is shown on the physical braille display and the virtual
182 * braille captions display. 273 * braille captions display.
183 * @private 274 * @private
184 */ 275 */
185 cvox.BrailleDisplayManager.prototype.refresh_ = function() { 276 cvox.BrailleDisplayManager.prototype.refresh_ = function() {
186 if (!this.displayState_.available) { 277 if (!this.displayState_.available || this.displayingImage_) {
David Tseng 2017/02/24 05:39:46 Returns also if braille is frozen.
dmazzoni 2017/02/27 06:56:23 Freezing is handled at a higher level than this, t
187 return; 278 return;
188 } 279 }
189 var brailleBuf = this.panStrategy_.getCurrentBrailleViewportContents(); 280 var brailleBuf = this.panStrategy_.getCurrentBrailleViewportContents();
190 var textBuf = this.panStrategy_.getCurrentTextViewportContents(); 281 var textBuf = this.panStrategy_.getCurrentTextViewportContents();
191 if (this.realDisplayState_.available) { 282 if (this.realDisplayState_.available) {
192 chrome.brailleDisplayPrivate.writeDots(brailleBuf, 283 chrome.brailleDisplayPrivate.writeDots(brailleBuf,
193 brailleBuf.byteLength, 1); 284 brailleBuf.byteLength, 1);
194 } 285 }
195 if (cvox.BrailleCaptionsBackground.isEnabled()) { 286 if (cvox.BrailleCaptionsBackground.isEnabled()) {
196 cvox.BrailleCaptionsBackground.setContent(textBuf, brailleBuf, 287 cvox.BrailleCaptionsBackground.setContent(textBuf, brailleBuf,
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 }; 459 };
369 460
370 /** 461 /**
371 * @param {boolean} wordWrap 462 * @param {boolean} wordWrap
372 * @private 463 * @private
373 */ 464 */
374 cvox.BrailleDisplayManager.prototype.updatePanStrategy_ = function(wordWrap) { 465 cvox.BrailleDisplayManager.prototype.updatePanStrategy_ = function(wordWrap) {
375 this.panStrategy_.setPanStrategy(wordWrap); 466 this.panStrategy_.setPanStrategy(wordWrap);
376 this.refresh_(); 467 this.refresh_();
377 }; 468 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698