worker.js (3277B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 "use strict"; 5 6 /** 7 * Import `createTask` to communicate with `devtools/shared/worker`. 8 */ 9 importScripts("resource://gre/modules/workers/require.js"); 10 const { createTask } = require("resource://devtools/shared/worker/helper.js"); 11 12 /** 13 * @see LineGraphWidget.prototype.setDataFromTimestamps in Graphs.js 14 * @param number id 15 * @param array timestamps 16 * @param number interval 17 * @param number duration 18 */ 19 createTask(self, "getBgRGBA", ({ dataTextBuf, dataBackgroundBuf }) => 20 getBgRGBA(dataTextBuf, dataBackgroundBuf) 21 ); 22 23 /** 24 * Calculates the luminance of a rgba tuple based on the formula given in 25 * https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef 26 * 27 * @param {Array} rgba An array with [r,g,b,a] values. 28 * @return {number} The calculated luminance. 29 */ 30 function calculateLuminance(rgba) { 31 for (let i = 0; i < 3; i++) { 32 rgba[i] /= 255; 33 rgba[i] = 34 rgba[i] < 0.03928 35 ? rgba[i] / 12.92 36 : Math.pow((rgba[i] + 0.055) / 1.055, 2.4); 37 } 38 return 0.2126 * rgba[0] + 0.7152 * rgba[1] + 0.0722 * rgba[2]; 39 } 40 41 /** 42 * Get RGBA or a range of RGBAs for the background pixels under the text. If luminance is 43 * uniform, only return one value of RGBA, otherwise return values that correspond to the 44 * min and max luminances. 45 * 46 * @param {ImageData} dataTextBuf 47 * pixel data for the accessible object with text visible. 48 * @param {ImageData} dataBackgroundBuf 49 * pixel data for the accessible object with transparent text. 50 * @return {object} 51 * RGBA or a range of RGBAs with min and max values. 52 */ 53 function getBgRGBA(dataTextBuf, dataBackgroundBuf) { 54 let min = [0, 0, 0, 1]; 55 let max = [255, 255, 255, 1]; 56 let minLuminance = 1; 57 let maxLuminance = 0; 58 const luminances = {}; 59 const dataText = new Uint8ClampedArray(dataTextBuf); 60 const dataBackground = new Uint8ClampedArray(dataBackgroundBuf); 61 62 let foundDistinctColor = false; 63 for (let i = 0; i < dataText.length; i = i + 4) { 64 const tR = dataText[i]; 65 const bgR = dataBackground[i]; 66 const tG = dataText[i + 1]; 67 const bgG = dataBackground[i + 1]; 68 const tB = dataText[i + 2]; 69 const bgB = dataBackground[i + 2]; 70 71 // Ignore pixels that are the same where pixels that are different between the two 72 // images are assumed to belong to the text within the node. 73 if (tR === bgR && tG === bgG && tB === bgB) { 74 continue; 75 } 76 77 foundDistinctColor = true; 78 79 const bgColor = `rgb(${bgR}, ${bgG}, ${bgB})`; 80 let luminance = luminances[bgColor]; 81 82 if (!luminance) { 83 // Calculate luminance for the RGB value and store it to only measure once. 84 luminance = calculateLuminance([bgR, bgG, bgB]); 85 luminances[bgColor] = luminance; 86 } 87 88 if (minLuminance >= luminance) { 89 minLuminance = luminance; 90 min = [bgR, bgG, bgB, 1]; 91 } 92 93 if (maxLuminance <= luminance) { 94 maxLuminance = luminance; 95 max = [bgR, bgG, bgB, 1]; 96 } 97 } 98 99 if (!foundDistinctColor) { 100 return null; 101 } 102 103 return minLuminance === maxLuminance ? { value: max } : { min, max }; 104 }