OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 /** @fileoverview Logic for panning a braille display within a line of braille | 5 /** @fileoverview Logic for panning a braille display within a line of braille |
6 * content that might not fit on a single display. | 6 * content that might not fit on a single display. |
7 */ | 7 */ |
8 | 8 |
9 goog.provide('cvox.PanStrategy'); | 9 goog.provide('cvox.PanStrategy'); |
10 | 10 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 */ | 101 */ |
102 get displaySize() { | 102 get displaySize() { |
103 return this.displaySize_; | 103 return this.displaySize_; |
104 }, | 104 }, |
105 | 105 |
106 /** | 106 /** |
107 * @return {{brailleOffset: number, textOffset: number}} The offset of | 107 * @return {{brailleOffset: number, textOffset: number}} The offset of |
108 * braille and text indices of the current slice. | 108 * braille and text indices of the current slice. |
109 */ | 109 */ |
110 get offsetsForSlices() { | 110 get offsetsForSlices() { |
111 return {brailleOffset: this.viewPort_.firstRow * this.displaySize_.columns, | 111 return { |
112 textOffset: this.brailleToText[this.viewPort_.firstRow * | 112 brailleOffset: this.viewPort_.firstRow * this.displaySize_.columns, |
113 this.displaySize_.columns]}; | 113 textOffset: this.brailleToText |
| 114 [this.viewPort_.firstRow * this.displaySize_.columns] |
| 115 }; |
114 }, | 116 }, |
115 | 117 |
116 /** | 118 /** |
117 * @return {number} The number of lines in the fixedBuffer. | 119 * @return {number} The number of lines in the fixedBuffer. |
118 */ | 120 */ |
119 get fixedLineCount() { | 121 get fixedLineCount() { |
120 return Math.ceil(this.fixedBuffer_.byteLength / this.displaySize_.columns); | 122 return Math.ceil(this.fixedBuffer_.byteLength / this.displaySize_.columns); |
121 }, | 123 }, |
122 | 124 |
123 /** | 125 /** |
124 * @return {number} The number of lines in the wrappedBuffer. | 126 * @return {number} The number of lines in the wrappedBuffer. |
125 */ | 127 */ |
126 get wrappedLineCount() { | 128 get wrappedLineCount() { |
127 return Math.ceil(this.wrappedBuffer_.byteLength / | 129 return Math.ceil( |
128 this.displaySize_.columns); | 130 this.wrappedBuffer_.byteLength / this.displaySize_.columns); |
129 }, | 131 }, |
130 | 132 |
131 /** | 133 /** |
132 * @return {Array<number>} The map of Braille cells to the first index of the | 134 * @return {Array<number>} The map of Braille cells to the first index of the |
133 * corresponding text character. | 135 * corresponding text character. |
134 */ | 136 */ |
135 get brailleToText() { | 137 get brailleToText() { |
136 if (this.panStrategyWrapped_) | 138 if (this.panStrategyWrapped_) |
137 return this.wrappedBrailleToText_; | 139 return this.wrappedBrailleToText_; |
138 else | 140 else |
139 return this.fixedBrailleToText_; | 141 return this.fixedBrailleToText_; |
140 }, | 142 }, |
141 | 143 |
142 /** | 144 /** |
143 * @return {ArrayBuffer} Buffer of the slice of braille cells within the | 145 * @return {ArrayBuffer} Buffer of the slice of braille cells within the |
144 * bounds of the viewport. | 146 * bounds of the viewport. |
145 */ | 147 */ |
146 getCurrentBrailleViewportContents: function() { | 148 getCurrentBrailleViewportContents: function() { |
147 var buf = this.panStrategyWrapped_ ? | 149 var buf = |
148 this.wrappedBuffer_ : this.fixedBuffer_; | 150 this.panStrategyWrapped_ ? this.wrappedBuffer_ : this.fixedBuffer_; |
149 return buf.slice(this.viewPort_.firstRow * this.displaySize_.columns, | 151 return buf.slice( |
| 152 this.viewPort_.firstRow * this.displaySize_.columns, |
150 (this.viewPort_.lastRow + 1) * this.displaySize_.columns); | 153 (this.viewPort_.lastRow + 1) * this.displaySize_.columns); |
151 }, | 154 }, |
152 | 155 |
153 /** | 156 /** |
154 * @return {string} String of the slice of text letters corresponding with | 157 * @return {string} String of the slice of text letters corresponding with |
155 * the current braille slice. | 158 * the current braille slice. |
156 */ | 159 */ |
157 getCurrentTextViewportContents: function() { | 160 getCurrentTextViewportContents: function() { |
158 var brailleToText = this.brailleToText; | 161 var brailleToText = this.brailleToText; |
159 // Index of last braille character in slice. | 162 // Index of last braille character in slice. |
(...skipping 21 matching lines...) Expand all Loading... |
181 | 184 |
182 /** | 185 /** |
183 * Sets the display size. This call may update the viewport. | 186 * Sets the display size. This call may update the viewport. |
184 * @param {number} rowCount the new row size, or {@code 0} if no display is | 187 * @param {number} rowCount the new row size, or {@code 0} if no display is |
185 * present. | 188 * present. |
186 * @param {number} columnCount the new column size, or {@code 0} | 189 * @param {number} columnCount the new column size, or {@code 0} |
187 * if no display is present. | 190 * if no display is present. |
188 */ | 191 */ |
189 setDisplaySize: function(rowCount, columnCount) { | 192 setDisplaySize: function(rowCount, columnCount) { |
190 this.displaySize_ = {rows: rowCount, columns: columnCount}; | 193 this.displaySize_ = {rows: rowCount, columns: columnCount}; |
191 this.setContent(this.textBuffer_, this.fixedBuffer_, | 194 this.setContent( |
192 this.fixedBrailleToText_, 0); | 195 this.textBuffer_, this.fixedBuffer_, this.fixedBrailleToText_, 0); |
193 }, | 196 }, |
194 | 197 |
195 /** | 198 /** |
196 * Sets the internal data structures that hold the fixed and wrapped buffers | 199 * Sets the internal data structures that hold the fixed and wrapped buffers |
197 * and maps. | 200 * and maps. |
198 * @param {string} textBuffer Text of the shown braille. | 201 * @param {string} textBuffer Text of the shown braille. |
199 * @param {!ArrayBuffer} translatedContent The new braille content. | 202 * @param {!ArrayBuffer} translatedContent The new braille content. |
200 * @param {Array<number>} fixedBrailleToText Map of Braille cells to the first | 203 * @param {Array<number>} fixedBrailleToText Map of Braille cells to the first |
201 * index of corresponding text letter. | 204 * index of corresponding text letter. |
202 * @param {number} targetPosition Target position. The viewport is changed | 205 * @param {number} targetPosition Target position. The viewport is changed |
203 * to overlap this position. | 206 * to overlap this position. |
204 */ | 207 */ |
205 setContent: function(textBuffer, translatedContent, fixedBrailleToText, | 208 setContent: function( |
206 targetPosition) { | 209 textBuffer, translatedContent, fixedBrailleToText, targetPosition) { |
207 this.viewPort_.firstRow = 0; | 210 this.viewPort_.firstRow = 0; |
208 this.viewPort_.lastRow = this.displaySize_.rows - 1; | 211 this.viewPort_.lastRow = this.displaySize_.rows - 1; |
209 this.fixedBrailleToText_ = fixedBrailleToText; | 212 this.fixedBrailleToText_ = fixedBrailleToText; |
210 this.wrappedBrailleToText_ = []; | 213 this.wrappedBrailleToText_ = []; |
211 this.textBuffer_ = textBuffer; | 214 this.textBuffer_ = textBuffer; |
212 this.fixedBuffer_ = translatedContent; | 215 this.fixedBuffer_ = translatedContent; |
213 | 216 |
214 // Convert the cells to Unicode braille pattern characters. | 217 // Convert the cells to Unicode braille pattern characters. |
215 var view = new Uint8Array(translatedContent); | 218 var view = new Uint8Array(translatedContent); |
216 var wrappedBrailleArray = []; | 219 var wrappedBrailleArray = []; |
217 | 220 |
218 var lastBreak = 0; | 221 var lastBreak = 0; |
219 var cellsPadded = 0; | 222 var cellsPadded = 0; |
220 var index; | 223 var index; |
221 for (index = 0; index < translatedContent.byteLength + cellsPadded; | 224 for (index = 0; index < translatedContent.byteLength + cellsPadded; |
222 index++) { | 225 index++) { |
223 // Is index at the beginning of a new line? | 226 // Is index at the beginning of a new line? |
224 if (index != 0 && index % this.displaySize_.columns == 0) { | 227 if (index != 0 && index % this.displaySize_.columns == 0) { |
225 if (view[index - cellsPadded] == 0) { | 228 if (view[index - cellsPadded] == 0) { |
226 // Delete all empty cells at the beginning of this line. | 229 // Delete all empty cells at the beginning of this line. |
227 while (index - cellsPadded < view.length && | 230 while (index - cellsPadded < view.length && |
228 view[index - cellsPadded] == 0) { | 231 view[index - cellsPadded] == 0) { |
229 cellsPadded--; | 232 cellsPadded--; |
230 } | 233 } |
231 index--; | 234 index--; |
232 lastBreak = index; | 235 lastBreak = index; |
233 } else if (view[index - cellsPadded - 1] != 0 && | 236 } else if ( |
| 237 view[index - cellsPadded - 1] != 0 && |
234 lastBreak % this.displaySize_.columns != 0) { | 238 lastBreak % this.displaySize_.columns != 0) { |
235 // If first cell is not empty, we need to move the whole word down to | 239 // If first cell is not empty, we need to move the whole word down to |
236 // this line and padd to previous line with 0's, from |lastBreak| to | 240 // this line and padd to previous line with 0's, from |lastBreak| to |
237 // index. The braille to text map is also updated. | 241 // index. The braille to text map is also updated. |
238 // If lastBreak is at the beginning of a line, that means the current | 242 // If lastBreak is at the beginning of a line, that means the current |
239 // word is bigger than |this.displaySize_.columns| so we shouldn't | 243 // word is bigger than |this.displaySize_.columns| so we shouldn't |
240 // wrap. | 244 // wrap. |
241 for (var j = lastBreak + 1; j < index; j++) { | 245 for (var j = lastBreak + 1; j < index; j++) { |
242 wrappedBrailleArray[j] = 0; | 246 wrappedBrailleArray[j] = 0; |
243 this.wrappedBrailleToText_[j] = this.wrappedBrailleToText_[j - 1]; | 247 this.wrappedBrailleToText_[j] = this.wrappedBrailleToText_[j - 1]; |
(...skipping 24 matching lines...) Expand all Loading... |
268 new Uint8Array(this.wrappedBuffer_).set(wrappedBrailleUint8Array); | 272 new Uint8Array(this.wrappedBuffer_).set(wrappedBrailleUint8Array); |
269 this.panToPosition_(targetPosition); | 273 this.panToPosition_(targetPosition); |
270 }, | 274 }, |
271 | 275 |
272 /** | 276 /** |
273 * If possible, changes the viewport to a part of the line that follows | 277 * If possible, changes the viewport to a part of the line that follows |
274 * the current viewport. | 278 * the current viewport. |
275 * @return {boolean} {@code true} if the viewport was changed. | 279 * @return {boolean} {@code true} if the viewport was changed. |
276 */ | 280 */ |
277 next: function() { | 281 next: function() { |
278 var contentLength = this.panStrategyWrapped_ ? | 282 var contentLength = |
279 this.wrappedLineCount : this.fixedLineCount; | 283 this.panStrategyWrapped_ ? this.wrappedLineCount : this.fixedLineCount; |
280 var newStart = this.viewPort_.lastRow + 1; | 284 var newStart = this.viewPort_.lastRow + 1; |
281 var newEnd; | 285 var newEnd; |
282 if (newStart + this.displaySize_.rows - 1 < contentLength) { | 286 if (newStart + this.displaySize_.rows - 1 < contentLength) { |
283 newEnd = newStart + this.displaySize_.rows - 1; | 287 newEnd = newStart + this.displaySize_.rows - 1; |
284 } else { | 288 } else { |
285 newEnd = contentLength - 1; | 289 newEnd = contentLength - 1; |
286 } | 290 } |
287 if (newEnd >= newStart) { | 291 if (newEnd >= newStart) { |
288 this.viewPort_ = {firstRow: newStart, lastRow: newEnd}; | 292 this.viewPort_ = {firstRow: newStart, lastRow: newEnd}; |
289 return true; | 293 return true; |
290 } | 294 } |
291 return false; | 295 return false; |
292 }, | 296 }, |
293 | 297 |
294 /** | 298 /** |
295 * If possible, changes the viewport to a part of the line that precedes | 299 * If possible, changes the viewport to a part of the line that precedes |
296 * the current viewport. | 300 * the current viewport. |
297 * @return {boolean} {@code true} if the viewport was changed. | 301 * @return {boolean} {@code true} if the viewport was changed. |
298 */ | 302 */ |
299 previous: function() { | 303 previous: function() { |
300 var contentLength = this.panStrategyWrapped_ ? | 304 var contentLength = |
301 this.wrappedLineCount : this.fixedLineCount; | 305 this.panStrategyWrapped_ ? this.wrappedLineCount : this.fixedLineCount; |
302 if (this.viewPort_.firstRow > 0) { | 306 if (this.viewPort_.firstRow > 0) { |
303 var newStart, newEnd; | 307 var newStart, newEnd; |
304 if (this.viewPort_.firstRow < this.displaySize_.rows) { | 308 if (this.viewPort_.firstRow < this.displaySize_.rows) { |
305 newStart = 0; | 309 newStart = 0; |
306 newEnd = Math.min(this.displaySize_.rows, contentLength); | 310 newEnd = Math.min(this.displaySize_.rows, contentLength); |
307 } else { | 311 } else { |
308 newEnd = this.viewPort_.firstRow - 1; | 312 newEnd = this.viewPort_.firstRow - 1; |
309 newStart = newEnd - this.displaySize_.rows + 1; | 313 newStart = newEnd - this.displaySize_.rows + 1; |
310 } | 314 } |
311 if (newStart <= newEnd) { | 315 if (newStart <= newEnd) { |
312 this.viewPort_ = {firstRow: newStart, lastRow: newEnd}; | 316 this.viewPort_ = {firstRow: newStart, lastRow: newEnd}; |
313 return true; | 317 return true; |
314 } | 318 } |
315 } | 319 } |
316 return false; | 320 return false; |
317 }, | 321 }, |
318 | 322 |
319 /** | 323 /** |
320 * Moves the viewport so that it overlaps a target position without taking | 324 * Moves the viewport so that it overlaps a target position without taking |
321 * the current viewport position into consideration. | 325 * the current viewport position into consideration. |
322 * @param {number} position Target position. | 326 * @param {number} position Target position. |
323 */ | 327 */ |
324 panToPosition_: function(position) { | 328 panToPosition_: function(position) { |
325 if (this.displaySize_.rows * this.displaySize_.columns > 0) { | 329 if (this.displaySize_.rows * this.displaySize_.columns > 0) { |
326 this.viewPort_ = {firstRow: -1, lastRow: -1}; | 330 this.viewPort_ = {firstRow: -1, lastRow: -1}; |
327 while (this.next() && (this.viewPort_.lastRow + 1) * | 331 while (this.next() && |
328 this.displaySize_.columns <= position) { | 332 (this.viewPort_.lastRow + 1) * this.displaySize_.columns <= |
| 333 position) { |
329 // Nothing to do. | 334 // Nothing to do. |
330 } | 335 } |
331 } else { | 336 } else { |
332 this.viewPort_ = {firstRow: position, lastRow: position}; | 337 this.viewPort_ = {firstRow: position, lastRow: position}; |
333 } | 338 } |
334 }, | 339 }, |
335 }; | 340 }; |
OLD | NEW |