Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* Import `createTask` to communicate with `devtools/shared/worker`.
*/
const { createTask } = require("resource://devtools/shared/worker/helper.js");
/**
* @see LineGraphWidget.prototype.setDataFromTimestamps in Graphs.js
* @param number id
* @param array timestamps
* @param number interval
* @param number duration
*/
createTask(self, "getBgRGBA", ({ dataTextBuf, dataBackgroundBuf }) =>
getBgRGBA(dataTextBuf, dataBackgroundBuf)
);
/**
* Calculates the luminance of a rgba tuple based on the formula given in
*
* @param {Array} rgba An array with [r,g,b,a] values.
* @return {Number} The calculated luminance.
*/
function calculateLuminance(rgba) {
for (let i = 0; i < 3; i++) {
rgba[i] /= 255;
rgba[i] =
rgba[i] < 0.03928
? rgba[i] / 12.92
: Math.pow((rgba[i] + 0.055) / 1.055, 2.4);
}
return 0.2126 * rgba[0] + 0.7152 * rgba[1] + 0.0722 * rgba[2];
}
/**
* Get RGBA or a range of RGBAs for the background pixels under the text. If luminance is
* uniform, only return one value of RGBA, otherwise return values that correspond to the
* min and max luminances.
* @param {ImageData} dataTextBuf
* pixel data for the accessible object with text visible.
* @param {ImageData} dataBackgroundBuf
* pixel data for the accessible object with transparent text.
* @return {Object}
* RGBA or a range of RGBAs with min and max values.
*/
function getBgRGBA(dataTextBuf, dataBackgroundBuf) {
let min = [0, 0, 0, 1];
let max = [255, 255, 255, 1];
let minLuminance = 1;
let maxLuminance = 0;
const luminances = {};
const dataText = new Uint8ClampedArray(dataTextBuf);
const dataBackground = new Uint8ClampedArray(dataBackgroundBuf);
let foundDistinctColor = false;
for (let i = 0; i < dataText.length; i = i + 4) {
const tR = dataText[i];
const bgR = dataBackground[i];
const tG = dataText[i + 1];
const bgG = dataBackground[i + 1];
const tB = dataText[i + 2];
const bgB = dataBackground[i + 2];
// Ignore pixels that are the same where pixels that are different between the two
// images are assumed to belong to the text within the node.
if (tR === bgR && tG === bgG && tB === bgB) {
continue;
}
foundDistinctColor = true;
const bgColor = `rgb(${bgR}, ${bgG}, ${bgB})`;
let luminance = luminances[bgColor];
if (!luminance) {
// Calculate luminance for the RGB value and store it to only measure once.
luminance = calculateLuminance([bgR, bgG, bgB]);
luminances[bgColor] = luminance;
}
if (minLuminance >= luminance) {
minLuminance = luminance;
min = [bgR, bgG, bgB, 1];
}
if (maxLuminance <= luminance) {
maxLuminance = luminance;
max = [bgR, bgG, bgB, 1];
}
}
if (!foundDistinctColor) {
return null;
}
return minLuminance === maxLuminance ? { value: max } : { min, max };
}