diff --git a/source.js b/source.js index c9b3851..fd5893e 100644 --- a/source.js +++ b/source.js @@ -469,6 +469,41 @@ var SVGtoPDF = function(doc, svg, x, y, options) { })); } function parseColor(raw) { + /** + * Converts an HSL color value to RGB. Conversion formula + * adapted from https://en.wikipedia.org/wiki/HSL_color_space. + * Assumes h, s, and l are contained in the set [0, 1] and + * returns r, g, and b in the set [0, 255]. + * + * @param {number} h The hue + * @param {number} s The saturation + * @param {number} l The lightness + * @return {Array} The RGB representation + */ + function hslToRgb(h, s, l) { + let r, g, b; + + if (s === 0) { + r = g = b = l; // achromatic + } else { + const q = l < 0.5 ? l * (1 + s) : l + s - l * s; + const p = 2 * l - q; + r = hueToRgb(p, q, h + 1/3); + g = hueToRgb(p, q, h); + b = hueToRgb(p, q, h - 1/3); + } + + return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; + } + + function hueToRgb(p, q, t) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1/6) return p + (q - p) * 6 * t; + if (t < 1/2) return q; + if (t < 2/3) return p + (q - p) * (2/3 - t) * 6; + return p; + } let temp, result; raw = (raw || '').trim(); if (temp = NamedColors[raw]) { @@ -493,6 +528,16 @@ var SVGtoPDF = function(doc, svg, x, y, options) { if (temp[1] < 256 && temp[2] < 256 && temp[3] < 256) { result = [temp.slice(1, 4), 1]; } + } else if (temp = raw.match(/^hsl\(\s*([0-9]+)(deg)?\s*,\s*([0-9]+)%\s*,\s*([0-9]+)%\s*\)$/i)) { + temp[1] = parseInt(temp[1]); temp[3] = parseInt(temp[3]); temp[4] = parseInt(temp[4]); + if (temp[1] <= 360 && temp[3] <= 100 && temp[4] <= 100) { + result = [hslToRgb(temp[1]/360, temp[3]/100, temp[4]/100), 1]; + } + } else if (temp = raw.match(/^hsla\(\s*([0-9]+)(deg)?\s*,\s*([0-9]+)%\s*,\s*([0-9]+)%\s*,\s*([0-9.]+)\s*\)$/i)) { + temp[1] = parseInt(temp[1]); temp[3] = parseInt(temp[3]); temp[4] = parseInt(temp[4]); temp[5] = parseFloat(temp[5]); + if (temp[1] <= 360 && temp[3] <= 100 && temp[4] <= 100 && temp[5] <= 1) { + result = [hslToRgb(temp[1]/360, temp[3]/100, temp[4]/100), temp[5]]; + } } else if (temp = raw.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i)) { result = [[parseInt(temp[1], 16), parseInt(temp[2], 16), parseInt(temp[3], 16)], 1]; } else if (temp = raw.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i)) {