Link webgl directly to browser/Color
This commit is contained in:
@@ -11,6 +11,7 @@ import { throwIfFalsy } from '../WebglUtils';
|
||||
import { IColor } from 'browser/Types';
|
||||
import { IDisposable } from 'xterm';
|
||||
import { AttributeData } from 'common/buffer/AttributeData';
|
||||
import { toCss, ensureContrastRatioRgba } from 'browser/Color';
|
||||
|
||||
// In practice we're probably never going to exhaust a texture this large. For debugging purposes,
|
||||
// however, it can be useful to set this to a really tiny value, to verify that LRU eviction works.
|
||||
@@ -543,120 +544,3 @@ function getBgColor(bg: number): number {
|
||||
default: return -1; // CM_DEFAULT defaults to -1
|
||||
}
|
||||
}
|
||||
|
||||
export function toCss(r: number, g: number, b: number): string {
|
||||
return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}`;
|
||||
}
|
||||
|
||||
export function toRgba(r: number, g: number, b: number, a: number = 0xFF): number {
|
||||
// >>> 0 forces an unsigned int
|
||||
return (r << 24 | g << 16 | b << 8 | a) >>> 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio
|
||||
* between two colors.
|
||||
* @param rgb The color to use.
|
||||
* @see https://www.w3.org/TR/WCAG20/#relativeluminancedef
|
||||
*/
|
||||
export function rgbRelativeLuminance(rgb: number): number {
|
||||
return rgbRelativeLuminance2(
|
||||
(rgb >> 16) & 0xFF,
|
||||
(rgb >> 8 ) & 0xFF,
|
||||
(rgb ) & 0xFF);
|
||||
}
|
||||
|
||||
export function rgbRelativeLuminance2(r: number, g: number, b: number): number {
|
||||
const rs = r / 255;
|
||||
const gs = g / 255;
|
||||
const bs = b / 255;
|
||||
const rr = rs <= 0.03928 ? rs / 12.92 : Math.pow((rs + 0.055) / 1.055, 2.4);
|
||||
const rg = gs <= 0.03928 ? gs / 12.92 : Math.pow((gs + 0.055) / 1.055, 2.4);
|
||||
const rb = bs <= 0.03928 ? bs / 12.92 : Math.pow((bs + 0.055) / 1.055, 2.4);
|
||||
return rr * 0.2126 + rg * 0.7152 + rb * 0.0722;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the contrast ratio between two relative luminance values.
|
||||
* @param l1 The first relative luminance.
|
||||
* @param l2 The first relative luminance.
|
||||
* @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef
|
||||
*/
|
||||
export function contrastRatio(l1: number, l2: number): number {
|
||||
if (l1 < l2) {
|
||||
return (l2 + 0.05) / (l1 + 0.05);
|
||||
}
|
||||
return (l1 + 0.05) / (l2 + 0.05);
|
||||
}
|
||||
|
||||
function rgbaToColor(r: number, g: number, b: number): IColor {
|
||||
return {
|
||||
css: toCss(r, g, b),
|
||||
rgba: toRgba(r, g, b)
|
||||
};
|
||||
}
|
||||
|
||||
export function ensureContrastRatioRgba(bgRgba: number, fgRgba: number, ratio: number): number | undefined {
|
||||
const bgL = rgbRelativeLuminance(bgRgba >> 8);
|
||||
const fgL = rgbRelativeLuminance(fgRgba >> 8);
|
||||
const cr = contrastRatio(bgL, fgL);
|
||||
if (cr < ratio) {
|
||||
if (fgL < bgL) {
|
||||
return reduceLuminance(bgRgba, fgRgba, ratio);
|
||||
}
|
||||
return increaseLuminance(bgRgba, fgRgba, ratio);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function ensureContrastRatio(bg: IColor, fg: IColor, ratio: number): IColor | undefined {
|
||||
const result = ensureContrastRatioRgba(bg.rgba, fg.rgba, ratio);
|
||||
if (!result) {
|
||||
return undefined;
|
||||
}
|
||||
return rgbaToColor(
|
||||
(result >> 24 & 0xFF),
|
||||
(result >> 16 & 0xFF),
|
||||
(result >> 8 & 0xFF)
|
||||
);
|
||||
}
|
||||
|
||||
export function reduceLuminance(bgRgba: number, fgRgba: number, ratio: number): number {
|
||||
// This is a naive but fast approach to reducing luminance as converting to
|
||||
// HSL and back is expensive
|
||||
const bgR = (bgRgba >> 24) & 0xFF;
|
||||
const bgG = (bgRgba >> 16) & 0xFF;
|
||||
const bgB = (bgRgba >> 8) & 0xFF;
|
||||
let fgR = (fgRgba >> 24) & 0xFF;
|
||||
let fgG = (fgRgba >> 16) & 0xFF;
|
||||
let fgB = (fgRgba >> 8) & 0xFF;
|
||||
let cr = contrastRatio(rgbRelativeLuminance2(fgR, fgB, fgG), rgbRelativeLuminance2(bgR, bgG, bgB));
|
||||
while (cr < ratio && (fgR > 0 || fgG > 0 || fgB > 0)) {
|
||||
// Reduce by 10% until the ratio is hit
|
||||
fgR -= Math.max(0, Math.ceil(fgR * 0.1));
|
||||
fgG -= Math.max(0, Math.ceil(fgG * 0.1));
|
||||
fgB -= Math.max(0, Math.ceil(fgB * 0.1));
|
||||
cr = contrastRatio(rgbRelativeLuminance2(fgR, fgB, fgG), rgbRelativeLuminance2(bgR, bgG, bgB));
|
||||
}
|
||||
return fgR << 24 | fgG << 16 | fgB << 8 | 0xFF;
|
||||
}
|
||||
|
||||
export function increaseLuminance(bgRgba: number, fgRgba: number, ratio: number): number {
|
||||
// This is a naive but fast approach to increasing luminance as converting to
|
||||
// HSL and back is expensive
|
||||
const bgR = (bgRgba >> 24) & 0xFF;
|
||||
const bgG = (bgRgba >> 16) & 0xFF;
|
||||
const bgB = (bgRgba >> 8) & 0xFF;
|
||||
let fgR = (fgRgba >> 24) & 0xFF;
|
||||
let fgG = (fgRgba >> 16) & 0xFF;
|
||||
let fgB = (fgRgba >> 8) & 0xFF;
|
||||
let cr = contrastRatio(rgbRelativeLuminance2(fgR, fgB, fgG), rgbRelativeLuminance2(bgR, bgG, bgB));
|
||||
while (cr < ratio && (fgR < 0xFF || fgG < 0xFF || fgB < 0xFF)) {
|
||||
// Increase by 10% until the ratio is hit
|
||||
fgR = Math.min(0xFF, fgR + Math.ceil((255 - fgR) * 0.1));
|
||||
fgG = Math.min(0xFF, fgG + Math.ceil((255 - fgG) * 0.1));
|
||||
fgB = Math.min(0xFF, fgB + Math.ceil((255 - fgB) * 0.1));
|
||||
cr = contrastRatio(rgbRelativeLuminance2(fgR, fgB, fgG), rgbRelativeLuminance2(bgR, bgG, bgB));
|
||||
}
|
||||
return fgR << 24 | fgG << 16 | fgB << 8 | 0xFF;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user