From d1c1c881d089eaa6a84929b863c6878ae42ae508 Mon Sep 17 00:00:00 2001 From: Patrick Martin Date: Thu, 3 Oct 2024 14:05:29 -0700 Subject: [PATCH] Reworked color interperetation. Fixed two bugs related to color interperetation. --- include/color.js | 4 +- scripts/commands/update-dependencies.sh | 0 src/color.js | 84 ++++++++++++++++--------- src/lib/codepage.js | 2 +- 4 files changed, 58 insertions(+), 32 deletions(-) mode change 100644 => 100755 scripts/commands/update-dependencies.sh diff --git a/include/color.js b/include/color.js index c554447..54099ef 100644 --- a/include/color.js +++ b/include/color.js @@ -21,9 +21,9 @@ sabre.cleanRawColor = function(raw){return "";}; let SSAColor; /** - * @type {function(new:SSAColor,number=,number=,number=,number=)} + * @type {function(new:SSAColor,number=,number=,number=,number=,number=)} */ -sabre.SSAColor = function (r, g, b, a) {}; +sabre.SSAColor = function (r, g, b, a, bitDepth) {}; /** * @typedef {!{ diff --git a/scripts/commands/update-dependencies.sh b/scripts/commands/update-dependencies.sh old mode 100644 new mode 100755 diff --git a/src/color.js b/src/color.js index 79a23c9..cce8565 100644 --- a/src/color.js +++ b/src/color.js @@ -6,6 +6,41 @@ |- */ +/** + * Convert n-bit arbitrarily-ordered color to a Object containing floating point representations of it's components. + * @param {number} color the n-bit color. + * @param {number=} bitDepth the bit depth of the color components (defaults to 8). + * @param {Array=} componentOrder the order of the color components (defaults to ABGR). + * @param {Array=} invertChannel whether to invert the coresponding channel (defaults to [true,false,false,false]). + * @return {Object} the resulting color data. + * @private + */ +function colorToArray (color, bitDepth, componentOrder, invertChannel) { + let components = ["r", "g", "b", "a"]; + if(typeof componentOrder === "object" && Array.isArray(componentOrder)) { + components = componentOrder.slice().reverse(); + } + invertChannel = invertChannel ?? [true, false, false, false]; + if(invertChannel.length !== components.length) + throw new Error("invertChannel must be the same length as componentOrder."); + bitDepth = bitDepth ?? 8; + if(bitDepth < 1 || bitDepth > 32) + throw new Error("bitDepth must be between 1 and 32 (inclusive)."); + if(components.length * bitDepth > 32) + throw new Error("Unable to represent color with more than 32 bits."); + const result = {}; + let i; + const mask = (1 << bitDepth) - 1; + for (i = 0; i < components.length; i++) { + result[components[i]] = (color & mask) / mask; + color = color >>> bitDepth; + } + for (i = 0; i < invertChannel.length; i++){ + result[components[i]] = 1 - result[components[i]]; + } + return result; +} + /** * Cleanup a raw color string. * @param {string} raw the raw string. @@ -19,35 +54,30 @@ sabre["cleanRawColor"] = function cleanRawColor (raw) { ); }; -sabre["SSAColor"] = function SSAColor (r, g, b, a) { - let obj = { +sabre["SSAColor"] = function SSAColor (r, g, b, a, bitDepth) { + const obj = { r: 0, g: 0, b: 0, a: 0 }; + if (typeof r === "number") { - if (r > 1.0 || r < 0) { - if (typeof g === "undefined") { - let n = r; - r = (n & 0xff) / 255; - n = n >>> 8; - g = (n & 0xff) / 255; - n = n >>> 8; - b = (n & 0xff) / 255; - n = n >>> 8; - a = (255 - (n & 0xff)) / 255; - } else { - r = (r & 0xff) / 255; - g = (g & 0xff) / 255; - b = (b & 0xff) / 255; - a = (a & 0xff) / 255; + if(typeof g !== "number") { + Object.assign(obj, colorToArray(r, bitDepth ?? 8)); + } else { + if(typeof bitDepth !== "number") { + obj.r = r; + obj.g = g; + obj.b = b; + obj.a = a; + }else{ + obj.r = r / ((1 << bitDepth) - 1); + obj.g = g / ((1 << bitDepth) - 1); + obj.b = b / ((1 << bitDepth) - 1); + obj.a = a / ((1 << bitDepth) - 1); } } - obj.r = r; - obj.g = g; - obj.b = b; - obj.a = a; } return Object.create(Object, { @@ -110,20 +140,16 @@ sabre["SSAOverrideColor"] = function SSAOverrideColor (r, g, b, a) { a: null }; if (typeof r === "number") { - if (r <= 1.0) obj.r = r; - else obj.r = (r & 0xff) / 255; + obj.r = r; } if (typeof g === "number") { - if (r <= 1.0) obj.g = g; - else obj.g = (g & 0xff) / 255; + obj.g = g; } if (typeof b === "number") { - if (r <= 1.0) obj.b = b; - else obj.b = (b & 0xff) / 255; + obj.b = b; } if (typeof a === "number") { - if (r <= 1.0) obj.a = a; - else obj.a = (a & 0xff) / 255; + obj.a = a; } return Object.create(Object, { diff --git a/src/lib/codepage.js b/src/lib/codepage.js index bdba62b..cb218f6 100644 --- a/src/lib/codepage.js +++ b/src/lib/codepage.js @@ -1,5 +1,5 @@ (function(){ -/*! /home/pie/Projects/SABRE.js/temp_files/codepage.js (C) 2013-present SheetJS -- http://sheetjs.com */ +/*! /home/user/Projects/SABRE.js/temp_files/codepage.js (C) 2013-present SheetJS -- http://sheetjs.com */ /*jshint -W100 */ var cptable = {version:"1.15.0"}; cptable[1252] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();