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

Unified Diff: ui/accessibility/extensions/colorenhancer/src/cvd.js

Issue 984833004: Add color enhancer as a chromium accessibility extensions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More docs. Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: ui/accessibility/extensions/colorenhancer/src/cvd.js
diff --git a/ui/accessibility/extensions/colorenhancer/src/cvd.js b/ui/accessibility/extensions/colorenhancer/src/cvd.js
new file mode 100644
index 0000000000000000000000000000000000000000..12b2d904239372462088368f407b9819852142f1
--- /dev/null
+++ b/ui/accessibility/extensions/colorenhancer/src/cvd.js
@@ -0,0 +1,363 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+// ======= Global state =======
+
+var storedDelta = 0;
+var storedSeverity = 0;
+var storedType = 'PROTANOMALY';
+var storedSimulate = false;
+var curFilter = 0;
+
+
+// ======= 3x3 matrix ops =======
+
+var identityMatrix3x3 = [
+ [1, 0, 0],
+ [0, 1, 0],
+ [0, 0, 1]
+];
+
+
+/**
+ * TODO(mustaq): JsDoc
+ */
+function add3x3(m1, m2) {
+ var result = [];
+ for (var i = 0; i < 3; i++) {
+ result[i] = [];
+ for (var j = 0; j < 3; j++) {
+ result[i].push(m1[i][j] + m2[i][j]);
+ }
+ }
+ return result;
+}
+
+
+/**
+ * TODO(mustaq): JsDoc
+ */
+function sub3x3(m1, m2) {
+ var result = [];
+ for (var i = 0; i < 3; i++) {
+ result[i] = [];
+ for (var j = 0; j < 3; j++) {
+ result[i].push(m1[i][j] - m2[i][j]);
+ }
+ }
+ return result;
+}
+
+
+/**
+ * TODO(mustaq): JsDoc
+ */
+function mul3x3(m1, m2) {
+ var result = [];
+ for (var i = 0; i < 3; i++) {
+ result[i] = [];
+ for (var j = 0; j < 3; j++) {
+ var sum = 0;
+ for (var k = 0; k < 3; k++) {
+ sum += m1[i][k] * m2[k][j];
+ }
+ result[i].push(sum);
+ }
+ }
+ return result;
+}
+
+
+/**
+ * TODO(mustaq): JsDoc
+ */
+function mul3x3Scalar(m, k) {
+ var result = [];
+ for (var i = 0; i < 3; i++) {
+ result[i] = [];
+ for (var j = 0; j < 3; j++) {
+ result[i].push(k * m[i][j]);
+ }
+ }
+ return result;
+}
+
+
+// ======= CVD parameters =======
+/**
+ * Parameters for simulating color vision deficiency.
+ * Source:
+ * http://www.inf.ufrgs.br/~oliveira/pubs_files/CVD_Simulation/CVD_Simulation.html
+ * Original Research Paper:
+ * http://www.inf.ufrgs.br/~oliveira/pubs_files/CVD_Simulation/Machado_Oliveira_Fernandes_CVD_Vis2009_final.pdf
+ *
+ * @enum {string}
+ */
+var cvdSimulationParams = {
+ PROTANOMALY: [
+ [0.4720, -1.2946, 0.9857],
+ [-0.6128, 1.6326, 0.0187],
+ [0.1407, -0.3380, -0.0044],
+ [-0.1420, 0.2488, 0.0044],
+ [0.1872, -0.3908, 0.9942],
+ [-0.0451, 0.1420, 0.0013],
+ [0.0222, -0.0253, -0.0004],
+ [-0.0290, -0.0201, 0.0006],
+ [0.0068, 0.0454, 0.9990]
+ ],
+ DEUTERANOMALY: [
+ [0.5442, -1.1454, 0.9818],
+ [-0.7091, 1.5287, 0.0238],
+ [0.1650, -0.3833, -0.0055],
+ [-0.1664, 0.4368, 0.0056],
+ [0.2178, -0.5327, 0.9927],
+ [-0.0514, 0.0958, 0.0017],
+ [0.0180, -0.0288, -0.0006],
+ [-0.0232, -0.0649, 0.0007],
+ [0.0052, 0.0360, 0.9998]
+ ],
+ TRITANOMALY: [
+ [0.4275, -0.0181, 0.9307],
+ [-0.2454, 0.0013, 0.0827],
+ [-0.1821, 0.0168, -0.0134],
+ [-0.1280, 0.0047, 0.0202],
+ [0.0233, -0.0398, 0.9728],
+ [0.1048, 0.0352, 0.0070],
+ [-0.0156, 0.0061, 0.0071],
+ [0.3841, 0.2947, 0.0151],
+ [-0.3685, -0.3008, 0.9778]
+ ]
+};
+
+
+// TODO(mustaq): A common matrix for all types? E.g. Kevin's experiment
+// suggested: Mx[1][0] = 0.7+0.3*delta and Mx[2][0] = 0.7-0.3*delta
+/**
+ * TODO(mustaq): JsDoc
+ *
+ * @enum {string}
+ */
+var cvdCorrectionParams = {
+ PROTANOMALY: {
+ addendum: [
+ [-1.0, 0.0, 0.0],
+ [0.5, 1.0, 0.0],
+ [1.5, 0.0, 1.0]
+ ],
+ delta_factor: [
+ [0.0, 0.0, 0.0],
+ [1.0, 0.0, 0.0],
+ [-1.0, 0.0, 0.0]
+ ]
+ },
+ DEUTERANOMALY: {
+ addendum: [
+ [1.0, 0.5, 0.0],
+ [0.5, -1.0, 0.0],
+ [1.5, 1.5, 1.0]
+ ],
+ delta_factor: [
+ [0.0, 1.0, 0.0],
+ [0.0, 0.0, 0.0],
+ [0.0, -1.0, 0.0]
+ ]
+ },
+ TRITANOMALY: {
+ addendum: [
+ [1.0, 0.0, 1.5],
+ [0.0, 1.0, 0.5],
+ [0.0, 0.0, -1.0]
+ ],
+ delta_factor: [
+ [0.0, 0.0, -1.0],
+ [0.0, 0.0, 1.0],
+ [0.0, 0.0, 0.0]
+ ]
+ }
+};
+
+
+// ======= CVD matrix builders =======
+
+/**
+ * TODO(mustaq): JsDoc
+ */
+function getCvdSimulationMatrix(cvdType, severity) {
+ var cvdSimulationParam = cvdSimulationParams[cvdType];
+ var severity2 = severity * severity;
+ var matrix = [];
+ for (var i = 0; i < 3; i++) {
+ var row = [];
+ for (var j = 0; j < 3; j++) {
+ var paramRow = i*3+j;
+ var val = cvdSimulationParam[paramRow][0] * severity2
+ + cvdSimulationParam[paramRow][1] * severity
+ + cvdSimulationParam[paramRow][2];
+ row.push(val);
+ }
+ matrix.push(row);
+ }
+ return matrix;
+}
+
+
+/**
+ * TODO(mustaq): JsDoc
+ */
+function getCvdCorrectionMatrix(cvdType, delta) {
+ cvdCorrectionParam = cvdCorrectionParams[cvdType];
+ // TODO(mustaq): Perhaps nuke full-matrix operations after experiment.
+ return add3x3(cvdCorrectionParam['addendum'],
+ mul3x3Scalar(cvdCorrectionParam['delta_factor'], delta));
+}
+
+
+/**
+ * TODO(mustaq): JsDoc
+ */
+function getCvdMatrixAsString(cvdType, severity, delta, simulate) {
+ var effectiveMatrix = getCvdSimulationMatrix(cvdType, severity);
+
+ if (!simulate) {
+ var cvdCorrectionMatrix = getCvdCorrectionMatrix(cvdType, delta);
+ var tmpProduct = mul3x3(cvdCorrectionMatrix, effectiveMatrix);
+
+ effectiveMatrix = sub3x3(
+ add3x3(identityMatrix3x3, cvdCorrectionMatrix),
+ tmpProduct);
+ }
+
+ var outputRows = [];
+ for (var i = 0; i < 3; i++) {
+ outputRows.push(effectiveMatrix[i].join(' ') + ' 0 0');
+ }
+ // Add the alpha row
+ outputRows.push('0 0 0 1 0');
+ return outputRows.join(' ');
+}
+
+
+// ======= Page linker =======
+
+var svgDefaultMatrix =
+ '1 0 0 0 0 ' +
+ '0 1 0 0 0 ' +
+ '0 0 1 0 0 ' +
+ '0 0 0 1 0';
+
+var svgContent =
+ '<svg xmlns='http://www.w3.org/2000/svg' version='1.1'>' +
+ ' <defs>' +
+ ' <filter id='cvd_extension_0'>' +
+ ' <feColorMatrix id='cvd_filter_matrix_0' type='matrix' values='' +
+ svgDefaultMatrix + ''/>' +
+ ' </filter>' +
+ ' <filter id='cvd_extension_1'>' +
+ ' <feColorMatrix id='cvd_filter_matrix_1' type='matrix' values='' +
+ svgDefaultMatrix + ''/>' +
+ ' </filter>' +
+ ' </defs>' +
+ '</svg>';
+
+/**
+ * Checks for svg filter matrix presence and append to DOM if not present.
+ */
+function addSvgIfMissing() {
+ var wrap = document.getElementById('cvd_extension_svg_filter');
+ if (!wrap) {
+ wrap = document.createElement('span');
+ wrap.id = 'cvd_extension_svg_filter';
+ wrap.setAttribute('hidden', '');
+ wrap.innerHTML = svgContent;
+ document.body.appendChild(wrap);
+ }
+}
+
+
+/**
+ * Update matrix when config values change.
+ */
+function update() {
+ if (!document.body) {
+ document.addEventListener('DOMContentLoaded', update);
+ return;
+ }
+ addSvgIfMissing();
+ var next = 1 - curFilter;
+
+ debugPrint(
+ 'Setting matrix#' + next + ' to ' +
+ getCvdMatrixAsString(
+ storedType, storedSeverity, storedDelta, storedSimulate));
+
+ var matrix = document.getElementById('cvd_filter_matrix_' + next);
+ matrix.setAttribute(
+ 'values', getCvdMatrixAsString(
+ storedType, storedSeverity, storedDelta, storedSimulate));
+
+ var html = document.documentElement;
+ html.classList.remove('filter' + curFilter);
+ html.offsetTop;
+ html.classList.add('filter' + next);
+
+ curFilter = next;
+
+ // TODO(wnwen): Figure out whether this hack is still necessary.
+ window.scrollBy(0, 1);
+ window.scrollBy(0, -1);
+}
+
+
+/**
+ * Process request from background page.
+ */
+function onExtensionMessage(request) {
+ var changed = false;
+
+ if (request['delta'] !== undefined) {
+ var delta = request.delta;
+ if (storedDelta != delta) {
+ storedDelta = delta;
+ changed = true;
+ }
+ }
+
+ if (request['severity'] !== undefined) {
+ var severity = request.severity;
+ if (storedSeverity != severity) {
+ storedSeverity = severity;
+ changed = true;
+ }
+ }
+
+ if (request['type'] !== undefined) {
+ var type = request.type;
+ if (storedType != type) {
+ storedType = type;
+ changed = true;
+ }
+ }
+
+ if (request['simulate'] !== undefined) {
+ var simulate = request.simulate;
+ if (storedSimulate != simulate) {
+ storedSimulate = simulate;
+ changed = true;
+ }
+ }
+
+ if (changed)
+ update();
+}
+
+
+/**
+ * Prepare to process background messages and let it know to send initial
+ * values.
+ */
+(function initialize() {
+ chrome.extension.onRequest.addListener(onExtensionMessage);
+ chrome.extension.sendRequest({'init': true}, onExtensionMessage);
+})();
« no previous file with comments | « ui/accessibility/extensions/colorenhancer/src/common.js ('k') | ui/accessibility/extensions/colorenhancer/src/popup.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698