browsh/webext/test/fixtures/canvas_pixels.js

79 wiersze
2.5 KiB
JavaScript

// Generate fake pixel data, as if sreenshotting a canvas element.
//
// The RGB channels are repurposed to indicate the function they were created by
// and their position in their 1 dimensionsal array structure.
//
// If a [R, G, B] contains a non-zero value the following applies;
// R: The pixel's colour is due to text and was generated by withText()
// G: The pixel's colour is due to background and was generated by withText()
// B: The pixel's colour is due to background and was generated by withoutText()
//
// * The values express the pixel's position in the array.
// * G and B should always have the same values, but should never appear in the same
// [R, G, B] array.
export default class CanvasPixels {
constructor(dimensions) {
this.width = dimensions.dom.sub.width;
this.height = dimensions.dom.sub.height;
this.pixel_count = this.width * this.height * 4;
}
// Putting the index in the red channel indicates text. An index value in the green
// channel indicates that this is the withText() function yet the colour is being
// picked up from the background (as if it were the withoutText() function).
with_text() {
let x, y, index;
let pixels = [];
for (let i = 0; i < this.pixel_count; i += 4) {
x = (i / 4) % this.width;
y = Math.floor(i / 2 / 4 / this.width);
index = this._getIndexValue(i);
if (this._checkForCharacter(x, y)) {
pixels.push(index);
pixels.push(0);
} else {
pixels.push(0);
pixels.push(index);
}
pixels.push(0);
pixels.push(0);
}
return { data: pixels };
}
_getIndexValue(i) {
// Add 1 to distinguish the zero value. Because zero values mean that nothing was
// found.
return i / 4 + 1;
}
_checkForCharacter(x, y) {
const char = global.mock_DOM_text[y].charAt(x);
const mask_char = global.mock_DOM_template[y].charAt(x);
const isCharThere = !this._isNullOrWhiteSpace(char);
const isMaskThere = mask_char === "!";
return isCharThere && !isMaskThere;
}
_isNullOrWhiteSpace(str) {
return !str || str.length === 0 || /^\s*$/.test(str);
}
// Using the blue channel indicates that this sample was taken from the withoutText()
// function.
without_text() {
let pixels = [];
for (let i = 0; i < this.pixel_count; i += 4) {
pixels.push(0);
pixels.push(0);
pixels.push(this._getIndexValue(i));
pixels.push(0);
}
return { data: pixels };
}
scaled() {
return this.without_text();
}
}