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

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

Issue 2703663002: Display images in multiline Braille (Closed)
Patch Set: Fix test 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 this.displayingImage_ = false;
David Tseng 2017/02/22 18:15:24 js doc
dmazzoni 2017/02/24 00:19:41 Done.
71
70 translatorManager.addChangeListener(function() { 72 translatorManager.addChangeListener(function() {
71 this.translateContent_(this.content_, this.expansionType_); 73 this.translateContent_(this.content_, this.expansionType_);
72 }.bind(this)); 74 }.bind(this));
73 75
74 chrome.storage.onChanged.addListener(function(changes, area) { 76 chrome.storage.onChanged.addListener(function(changes, area) {
75 if (area == 'local' && 'brailleWordWrap' in changes) { 77 if (area == 'local' && 'brailleWordWrap' in changes) {
76 this.updatePanStrategy_(changes.brailleWordWrap.newValue); 78 this.updatePanStrategy_(changes.brailleWordWrap.newValue);
77 } 79 }
78 if (area == 'local' && ('virtualBrailleRows' in changes || 80 if (area == 'local' && ('virtualBrailleRows' in changes ||
79 'virtualBrailleColumns' in changes)) { 81 'virtualBrailleColumns' in changes)) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 113
112 /** 114 /**
113 * @param {!cvox.NavBraille} content Content to send to the braille display. 115 * @param {!cvox.NavBraille} content Content to send to the braille display.
114 * @param {!cvox.ExpandingBrailleTranslator.ExpansionType} expansionType 116 * @param {!cvox.ExpandingBrailleTranslator.ExpansionType} expansionType
115 * If the text has a {@code ValueSpan}, this indicates how that part 117 * If the text has a {@code ValueSpan}, this indicates how that part
116 * of the display content is expanded when translating to braille. 118 * of the display content is expanded when translating to braille.
117 * (See {@code cvox.ExpandingBrailleTranslator}). 119 * (See {@code cvox.ExpandingBrailleTranslator}).
118 */ 120 */
119 cvox.BrailleDisplayManager.prototype.setContent = function( 121 cvox.BrailleDisplayManager.prototype.setContent = function(
120 content, expansionType) { 122 content, expansionType) {
123 this.displayingImage_ = false;
121 this.translateContent_(content, expansionType); 124 this.translateContent_(content, expansionType);
122 }; 125 };
123 126
124 127
125 /** 128 /**
129 * Takes an image, in the form of a data url, and displays it in braille
130 * onto the physical braille display and the virtual braille captions display.
131 * @param {!string} imageUrl The image, in the form of a data url.
132 */
133 cvox.BrailleDisplayManager.prototype.setImageContent = function(imageUrl) {
134 this.displayingImage_ = true;
135 if (!this.displayState_.available) {
136 return;
137 }
138
139 var rows = this.displayState_.textRowCount;
140 var columns = this.displayState_.textColumnCount;
141 var imageDataUrl = imageUrl;
142 var imgElement = document.createElement('img');
143 imgElement.src = imageDataUrl;
144 var canvas = document.createElement('canvas');
145 var context = canvas.getContext('2d');
146 canvas.width = columns * 2;
147 canvas.height = rows * 4;
148 context.drawImage(imgElement, 0, 0, canvas.width, canvas.height);
149 var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
150 var data = imageData.data;
151 var outputData = [];
152
153 // Convert image to black and white.
154 for (var i = 0; i < data.length; i += 4) {
155 // Show if the alpha value is visible (above 20) and the pixel is not
156 // white (under 600).
157 var show = (data[i] +
158 data[i + 1] +
159 data[i + 2] <= 200 * 3) &&
160 (data[i + 3]) == 255;
161 outputData.push(show);
162 }
163
164 // Convert to Braille.
165 var buf = new ArrayBuffer(rows * columns);
166 var view = new Uint8Array(buf);
167 var coordsToBrailleDot = [0x1, 0x2, 0x4, 0x40, 0x8, 0x10, 0x20, 0x80];
168 for (var i = 0; i < rows; i++) {
169 for (var j = 0; j < columns; j++) {
170 //Index in braille array
171 var index = i * columns + j;
172 view[index] = 0;
173 for (var x = 0; x < 2; x++) {
174 for (var y = 0; y < 4; y++) {
175 if (outputData[((i * columns * 4 + j + y * columns) * 2 + x)])
176 view[index] += coordsToBrailleDot[x * 4 + y];
177 }
178 }
179 }
180 }
181
182 if (this.realDisplayState_.available) {
183 chrome.brailleDisplayPrivate.writeDots(
184 buf,
185 this.displayState_.textColumnCount,
186 this.displayState_.textRowCount);
187 }
188 if (cvox.BrailleCaptionsBackground.isEnabled()) {
189 cvox.BrailleCaptionsBackground.setImageContent(buf, rows, columns);
190 }
191 };
192
193
194 /**
126 * Sets the command listener. When a command is invoked, the listener will be 195 * 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 196 * 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 197 * 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 198 * 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. 199 * to cvox.BrailleDisplayManager.setContent, or null if no content was set.
131 * @param {function(!cvox.BrailleKeyEvent, !cvox.NavBraille)} func The listener. 200 * @param {function(!cvox.BrailleKeyEvent, !cvox.NavBraille)} func The listener.
132 */ 201 */
133 cvox.BrailleDisplayManager.prototype.setCommandListener = function(func) { 202 cvox.BrailleDisplayManager.prototype.setCommandListener = function(func) {
134 this.commandListener_ = func; 203 this.commandListener_ = func;
135 }; 204 };
136 205
137 206
138 /** 207 /**
139 * @param {!cvox.BrailleDisplayState} newState Display state reported 208 * @return {!cvox.BrailleDisplayState} The current display state.
209 */
210 cvox.BrailleDisplayManager.prototype.getDisplayState = function() {
211 return this.displayState_;
212 };
213
214
215 /**
216 * @param {{available: boolean, textRowCount: (number|undefined),
217 * textColumnCount: (number|undefined)}} newState Display state reported
David Tseng 2017/02/22 18:15:24 This should be cvox.BrailleDisplayState.
dmazzoni 2017/02/24 00:19:41 I did this on purpose. The extension API allows te
140 * by the extension API. 218 * by the extension API.
141 * @private 219 * @private
142 */ 220 */
143 cvox.BrailleDisplayManager.prototype.refreshDisplayState_ = function( 221 cvox.BrailleDisplayManager.prototype.refreshDisplayState_ = function(
144 newState) { 222 newState) {
145 var oldColumnCount = this.displayState_.textColumnCount || 0; 223 var oldColumnCount = this.displayState_.textColumnCount || 0;
146 var oldRowCount = this.displayState_.textRowCount || 0; 224 var oldRowCount = this.displayState_.textRowCount || 0;
147 var processDisplayState = function(displayState) { 225 var processDisplayState = function(displayState) {
148 this.displayState_ = displayState; 226 this.displayState_ = displayState;
149 var newColumnCount = displayState.textColumnCount || 0; 227 var newColumnCount = displayState.textColumnCount || 0;
150 var newRowCount = displayState.textRowCount || 0; 228 var newRowCount = displayState.textRowCount || 0;
151 229
152 if (oldColumnCount != newColumnCount || oldRowCount != newRowCount) { 230 if (oldColumnCount != newColumnCount || oldRowCount != newRowCount) {
153 this.panStrategy_.setDisplaySize(newRowCount, newColumnCount); 231 this.panStrategy_.setDisplaySize(newRowCount, newColumnCount);
154 } 232 }
155 this.refresh_(); 233 this.refresh_();
156 }.bind(this); 234 }.bind(this);
157 this.realDisplayState_ = newState; 235 this.realDisplayState_ = {
236 available: newState.available,
237 textRowCount: newState.textRowCount || 0,
238 textColumnCount: newState.textColumnCount || 0
239 };
158 if (newState.available) { 240 if (newState.available) {
159 processDisplayState(newState); 241 processDisplayState(newState);
160 // Update the dimensions of the virtual braille captions display to those 242 // Update the dimensions of the virtual braille captions display to those
161 // of a real physical display when one is plugged in. 243 // of a real physical display when one is plugged in.
162 } else { 244 } else {
163 cvox.BrailleCaptionsBackground.getVirtualDisplayState(processDisplayState); 245 cvox.BrailleCaptionsBackground.getVirtualDisplayState(processDisplayState);
164 } 246 }
165 }; 247 };
166 248
167 249
168 /** 250 /**
169 * Called when the state of braille captions changes. 251 * Called when the state of braille captions changes.
170 * @private 252 * @private
171 */ 253 */
172 cvox.BrailleDisplayManager.prototype.onCaptionsStateChanged_ = function() { 254 cvox.BrailleDisplayManager.prototype.onCaptionsStateChanged_ = function() {
173 // Force reevaluation of the display state based on our stored real 255 // Force reevaluation of the display state based on our stored real
174 // hardware display state, meaning that if a real display is connected, 256 // hardware display state, meaning that if a real display is connected,
175 // that takes precedence over the state from the captions 'virtual' display. 257 // that takes precedence over the state from the captions 'virtual' display.
176 this.refreshDisplayState_(this.realDisplayState_); 258 this.refreshDisplayState_(this.realDisplayState_);
177 }; 259 };
178 260
179 261
180 /** 262 /**
181 * Refreshes what is shown on the physical braille display and the virtual 263 * Refreshes what is shown on the physical braille display and the virtual
182 * braille captions display. 264 * braille captions display.
183 * @private 265 * @private
184 */ 266 */
185 cvox.BrailleDisplayManager.prototype.refresh_ = function() { 267 cvox.BrailleDisplayManager.prototype.refresh_ = function() {
186 if (!this.displayState_.available) { 268 if (!this.displayState_.available || this.displayingImage_) {
David Tseng 2017/02/22 18:15:24 Seems like you should get this to work without kee
dmazzoni 2017/02/24 00:19:41 They will have pretty different panning behavior,
187 return; 269 return;
188 } 270 }
189 var brailleBuf = this.panStrategy_.getCurrentBrailleViewportContents(); 271 var brailleBuf = this.panStrategy_.getCurrentBrailleViewportContents();
190 var textBuf = this.panStrategy_.getCurrentTextViewportContents(); 272 var textBuf = this.panStrategy_.getCurrentTextViewportContents();
191 if (this.realDisplayState_.available) { 273 if (this.realDisplayState_.available) {
192 chrome.brailleDisplayPrivate.writeDots(brailleBuf, 274 chrome.brailleDisplayPrivate.writeDots(brailleBuf,
193 brailleBuf.byteLength, 1); 275 brailleBuf.byteLength, 1);
194 } 276 }
195 if (cvox.BrailleCaptionsBackground.isEnabled()) { 277 if (cvox.BrailleCaptionsBackground.isEnabled()) {
196 cvox.BrailleCaptionsBackground.setContent(textBuf, brailleBuf, 278 cvox.BrailleCaptionsBackground.setContent(textBuf, brailleBuf,
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 }; 450 };
369 451
370 /** 452 /**
371 * @param {boolean} wordWrap 453 * @param {boolean} wordWrap
372 * @private 454 * @private
373 */ 455 */
374 cvox.BrailleDisplayManager.prototype.updatePanStrategy_ = function(wordWrap) { 456 cvox.BrailleDisplayManager.prototype.updatePanStrategy_ = function(wordWrap) {
375 this.panStrategy_.setPanStrategy(wordWrap); 457 this.panStrategy_.setPanStrategy(wordWrap);
376 this.refresh_(); 458 this.refresh_();
377 }; 459 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698